|
16 | 16 | #endif |
17 | 17 |
|
18 | 18 | #include <sys/syscall.h> /* Definition of SYS_* constants */ |
| 19 | +#include <sys/resource.h> |
19 | 20 | #include <sys/types.h> |
| 21 | +#include <sys/utsname.h> |
20 | 22 | #include <ucontext.h> |
21 | 23 | #include <unistd.h> |
22 | 24 |
|
| 25 | +#include <fstream> |
| 26 | +#include <string> |
| 27 | + |
23 | 28 | std::atomic<TimerCreateCpuProfiler*> TimerCreateCpuProfiler::Instance = nullptr; |
24 | 29 |
|
25 | 30 | TimerCreateCpuProfiler::TimerCreateCpuProfiler( |
@@ -75,6 +80,32 @@ const char* TimerCreateCpuProfiler::GetName() |
75 | 80 |
|
76 | 81 | bool TimerCreateCpuProfiler::StartImpl() |
77 | 82 | { |
| 83 | + // Dump environment info to help diagnose timer_create failures |
| 84 | + { |
| 85 | + struct utsname uts; |
| 86 | + if (uname(&uts) == 0) |
| 87 | + { |
| 88 | + Log::Info("Kernel: ", uts.sysname, " ", uts.release, " ", uts.machine); |
| 89 | + } |
| 90 | + |
| 91 | + struct rlimit rl; |
| 92 | + if (getrlimit(RLIMIT_SIGPENDING, &rl) == 0) |
| 93 | + { |
| 94 | + Log::Info("RLIMIT_SIGPENDING: soft=", rl.rlim_cur, " hard=", rl.rlim_max); |
| 95 | + } |
| 96 | + |
| 97 | + std::ifstream status("/proc/self/status"); |
| 98 | + std::string line; |
| 99 | + while (std::getline(status, line)) |
| 100 | + { |
| 101 | + if (line.rfind("SigQ:", 0) == 0) |
| 102 | + { |
| 103 | + Log::Info("Signal queue at startup: ", line); |
| 104 | + break; |
| 105 | + } |
| 106 | + } |
| 107 | + } |
| 108 | + |
78 | 109 | if (_pSignalManager == nullptr) |
79 | 110 | { |
80 | 111 | Log::Info("Profiler Signal manager was not correctly initialized (see previous messages).", |
@@ -319,7 +350,26 @@ void TimerCreateCpuProfiler::RegisterThreadImpl(ManagedThreadInfo* threadInfo) |
319 | 350 | clockid_t clock = ((~tid) << 3) | 6; // CPUCLOCK_SCHED | CPUCLOCK_PERTHREAD_MASK thread_cpu_clock(tid); |
320 | 351 | if (syscall(__NR_timer_create, clock, &sev, &timerId) < 0) |
321 | 352 | { |
322 | | - Log::Error("Call to timer_create failed for thread ", tid, ". Error: ", strerror(errno)); |
| 353 | + auto err = errno; |
| 354 | + Log::Error("Call to timer_create failed for thread ", tid, |
| 355 | + ". errno=", err, " (", strerror(err), ")"); |
| 356 | + |
| 357 | + struct rlimit rl; |
| 358 | + if (getrlimit(RLIMIT_SIGPENDING, &rl) == 0) |
| 359 | + { |
| 360 | + Log::Error("RLIMIT_SIGPENDING: soft=", rl.rlim_cur, " hard=", rl.rlim_max); |
| 361 | + } |
| 362 | + |
| 363 | + std::ifstream status("/proc/self/status"); |
| 364 | + std::string line; |
| 365 | + while (std::getline(status, line)) |
| 366 | + { |
| 367 | + if (line.rfind("SigQ:", 0) == 0) |
| 368 | + { |
| 369 | + Log::Error("Signal queue: ", line); |
| 370 | + break; |
| 371 | + } |
| 372 | + } |
323 | 373 | return; |
324 | 374 | } |
325 | 375 |
|
|
0 commit comments