bool Start() { stopTrace(); // stop old startTrace(); if (!m_kernelSession.Init(true, KERNEL_LOGGER_NAMEW) || !m_heapSession.Init(true, HEAP_LOGGER_NAMEW)) { stopTrace(); return false; } m_kernelSession.Start(); m_heapSession.Start(); m_flusher.Start(); _ThreadBase::Start(); return true; }
void Stop() { _ThreadBase::SetNeedExit(); m_flusher.SetNeedExit(); stopTrace(); m_kernelSession.Stop(); m_heapSession.Stop(); _ThreadBase::Stop(); m_flusher.Stop(); }
void Tracer::startTrace(string filename) { if (m_enabled) { stopTrace(); } if (filename != "") { m_trace_file.open(filename.c_str()); if (m_trace_file.fail()) { cout << "Error: error opening file '" << filename << "'" << endl; cout << "Trace not enabled." << endl; return; } cout << "Request trace enabled to output file '" << filename << "'" << endl; m_enabled = true; } }
int main(int argc, char **argv) { bool isRoot = (getuid() == 0); if (argc == 2 && 0 == strcmp(argv[1], "--help")) { showHelp(argv[0]); exit(0); } for (;;) { int ret; ret = getopt(argc, argv, "b:gcidflst:wz"); if (ret < 0) { break; } switch(ret) { case 'g': if (!isRoot) { fprintf(stderr, "error: tracing GPU power state requires root privileges\n"); exit(1); } g_traceGpuPower = true; break; case 'b': g_traceBufferSizeKB = atoi(optarg); break; case 'c': g_traceOverwrite = true; break; case 'i': g_traceCpuIdle = true; break; case 'l': g_traceGovernorLoad = true; break; case 'd': if (!isRoot) { fprintf(stderr, "error: tracing disk activity requires root privileges\n"); exit(1); } g_traceDisk = true; break; case 'f': g_traceCpuFrequency = true; break; case 's': g_traceSchedSwitch = true; break; case 't': g_traceDurationSeconds = atoi(optarg); break; case 'w': if (!isRoot) { fprintf(stderr, "error: tracing kernel work queues requires root privileges\n"); exit(1); } g_traceWorkqueue = true; break; case 'z': g_compress = true; break; default: fprintf(stderr, "\n"); showHelp(argv[0]); exit(-1); break; } } registerSigHandler(); bool ok = startTrace(isRoot); if (ok) { printf("capturing trace..."); fflush(stdout); // We clear the trace after starting it because tracing gets enabled for // each CPU individually in the kernel. Having the beginning of the trace // contain entries from only one CPU can cause "begin" entries without a // matching "end" entry to show up if a task gets migrated from one CPU to // another. ok = clearTrace(); if (ok) { // Sleep to allow the trace to be captured. struct timespec timeLeft; timeLeft.tv_sec = g_traceDurationSeconds; timeLeft.tv_nsec = 0; do { if (g_traceAborted) { break; } } while (nanosleep(&timeLeft, &timeLeft) == -1 && errno == EINTR); } } // Stop the trace and restore the default settings. stopTrace(isRoot); if (ok) { if (!g_traceAborted) { printf(" done\nTRACE:\n"); fflush(stdout); dumpTrace(); } else { printf("\ntrace aborted.\n"); fflush(stdout); } clearTrace(); } else { fprintf(stderr, "unable to start tracing\n"); } // Reset the trace buffer size to 1. setTraceBufferSizeKB(1); return g_traceAborted ? 1 : 0; }
str CMDstopTrace(void *res) { (void) res; return stopTrace(0); }
str CMDstopTracePath(void *res, str *path) { (void) res; return stopTrace(*path); }