profiler.cc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
  2. // Copyright (c) 2005, Google Inc.
  3. // All rights reserved.
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. // ---
  31. // Author: Sanjay Ghemawat
  32. // Chris Demetriou (refactoring)
  33. //
  34. // Profile current program by sampling stack-trace every so often
  35. #include "config.h"
  36. #include "getpc.h" // should be first to get the _GNU_SOURCE dfn
  37. #include <signal.h>
  38. #include <assert.h>
  39. #include <stdio.h>
  40. #include <errno.h>
  41. #include <string.h>
  42. #ifdef HAVE_UNISTD_H
  43. #include <unistd.h> // for getpid()
  44. #endif
  45. #if defined(HAVE_SYS_UCONTEXT_H)
  46. #include <sys/ucontext.h>
  47. #elif defined(HAVE_UCONTEXT_H)
  48. #include <ucontext.h>
  49. #elif defined(HAVE_CYGWIN_SIGNAL_H)
  50. #include <cygwin/signal.h>
  51. typedef ucontext ucontext_t;
  52. #else
  53. typedef int ucontext_t; // just to quiet the compiler, mostly
  54. #endif
  55. #include <sys/time.h>
  56. #include <string>
  57. #include <gperftools/profiler.h>
  58. #include <gperftools/stacktrace.h>
  59. #include "base/commandlineflags.h"
  60. #include "base/logging.h"
  61. #include "base/googleinit.h"
  62. #include "base/spinlock.h"
  63. #include "base/sysinfo.h" /* for GetUniquePathFromEnv, etc */
  64. #include "profiledata.h"
  65. #include "profile-handler.h"
  66. #ifdef HAVE_CONFLICT_SIGNAL_H
  67. #include "conflict-signal.h" /* used on msvc machines */
  68. #endif
  69. using std::string;
  70. DEFINE_bool(cpu_profiler_unittest,
  71. EnvToBool("PERFTOOLS_UNITTEST", true),
  72. "Determines whether or not we are running under the \
  73. control of a unit test. This allows us to include or \
  74. exclude certain behaviours.");
  75. // Collects up all profile data. This is a singleton, which is
  76. // initialized by a constructor at startup. If no cpu profiler
  77. // signal is specified then the profiler lifecycle is either
  78. // manaully controlled via the API or attached to the scope of
  79. // the singleton (program scope). Otherwise the cpu toggle is
  80. // used to allow for user selectable control via signal generation.
  81. // This is very useful for profiling a daemon process without
  82. // having to start and stop the daemon or having to modify the
  83. // source code to use the cpu profiler API.
  84. class CpuProfiler {
  85. public:
  86. CpuProfiler();
  87. ~CpuProfiler();
  88. // Start profiler to write profile info into fname
  89. bool Start(const char* fname, const ProfilerOptions* options);
  90. // Stop profiling and write the data to disk.
  91. void Stop();
  92. // Write the data to disk (and continue profiling).
  93. void FlushTable();
  94. bool Enabled();
  95. void GetCurrentState(ProfilerState* state);
  96. static CpuProfiler instance_;
  97. private:
  98. // This lock implements the locking requirements described in the ProfileData
  99. // documentation, specifically:
  100. //
  101. // lock_ is held all over all collector_ method calls except for the 'Add'
  102. // call made from the signal handler, to protect against concurrent use of
  103. // collector_'s control routines. Code other than signal handler must
  104. // unregister the signal handler before calling any collector_ method.
  105. // 'Add' method in the collector is protected by a guarantee from
  106. // ProfileHandle that only one instance of prof_handler can run at a time.
  107. SpinLock lock_;
  108. ProfileData collector_;
  109. // Filter function and its argument, if any. (NULL means include all
  110. // samples). Set at start, read-only while running. Written while holding
  111. // lock_, read and executed in the context of SIGPROF interrupt.
  112. int (*filter_)(void*);
  113. void* filter_arg_;
  114. // Opaque token returned by the profile handler. To be used when calling
  115. // ProfileHandlerUnregisterCallback.
  116. ProfileHandlerToken* prof_handler_token_;
  117. // Sets up a callback to receive SIGPROF interrupt.
  118. void EnableHandler();
  119. // Disables receiving SIGPROF interrupt.
  120. void DisableHandler();
  121. // Signal handler that records the interrupted pc in the profile data.
  122. static void prof_handler(int sig, siginfo_t*, void* signal_ucontext,
  123. void* cpu_profiler);
  124. };
  125. // Signal handler that is registered when a user selectable signal
  126. // number is defined in the environment variable CPUPROFILESIGNAL.
  127. static void CpuProfilerSwitch(int signal_number)
  128. {
  129. bool static started = false;
  130. static unsigned profile_count = 0;
  131. static char base_profile_name[1024] = "\0";
  132. if (base_profile_name[0] == '\0') {
  133. if (!GetUniquePathFromEnv("CPUPROFILE", base_profile_name)) {
  134. RAW_LOG(FATAL,"Cpu profiler switch is registered but no CPUPROFILE is defined");
  135. return;
  136. }
  137. }
  138. if (!started)
  139. {
  140. char full_profile_name[1024];
  141. snprintf(full_profile_name, sizeof(full_profile_name), "%s.%u",
  142. base_profile_name, profile_count++);
  143. if(!ProfilerStart(full_profile_name))
  144. {
  145. RAW_LOG(FATAL, "Can't turn on cpu profiling for '%s': %s\n",
  146. full_profile_name, strerror(errno));
  147. }
  148. }
  149. else
  150. {
  151. ProfilerStop();
  152. }
  153. started = !started;
  154. }
  155. // Profile data structure singleton: Constructor will check to see if
  156. // profiling should be enabled. Destructor will write profile data
  157. // out to disk.
  158. CpuProfiler CpuProfiler::instance_;
  159. // Initialize profiling: activated if getenv("CPUPROFILE") exists.
  160. CpuProfiler::CpuProfiler()
  161. : prof_handler_token_(NULL) {
  162. // TODO(cgd) Move this code *out* of the CpuProfile constructor into a
  163. // separate object responsible for initialization. With ProfileHandler there
  164. // is no need to limit the number of profilers.
  165. if (getenv("CPUPROFILE") == NULL) {
  166. if (!FLAGS_cpu_profiler_unittest) {
  167. RAW_LOG(WARNING, "CPU profiler linked but no valid CPUPROFILE environment variable found\n");
  168. }
  169. return;
  170. }
  171. // We don't enable profiling if setuid -- it's a security risk
  172. #ifdef HAVE_GETEUID
  173. if (getuid() != geteuid()) {
  174. if (!FLAGS_cpu_profiler_unittest) {
  175. RAW_LOG(WARNING, "Cannot perform CPU profiling when running with setuid\n");
  176. }
  177. return;
  178. }
  179. #endif
  180. char *signal_number_str = getenv("CPUPROFILESIGNAL");
  181. if (signal_number_str != NULL) {
  182. long int signal_number = strtol(signal_number_str, NULL, 10);
  183. if (signal_number >= 1 && signal_number <= 64) {
  184. intptr_t old_signal_handler = reinterpret_cast<intptr_t>(signal(signal_number, CpuProfilerSwitch));
  185. if (old_signal_handler == 0) {
  186. RAW_LOG(INFO,"Using signal %d as cpu profiling switch", signal_number);
  187. } else {
  188. RAW_LOG(FATAL, "Signal %d already in use\n", signal_number);
  189. }
  190. } else {
  191. RAW_LOG(FATAL, "Signal number %s is invalid\n", signal_number_str);
  192. }
  193. } else {
  194. char fname[PATH_MAX];
  195. if (!GetUniquePathFromEnv("CPUPROFILE", fname)) {
  196. if (!FLAGS_cpu_profiler_unittest) {
  197. RAW_LOG(WARNING, "CPU profiler linked but no valid CPUPROFILE environment variable found\n");
  198. }
  199. return;
  200. }
  201. if (!Start(fname, NULL)) {
  202. RAW_LOG(FATAL, "Can't turn on cpu profiling for '%s': %s\n",
  203. fname, strerror(errno));
  204. }
  205. }
  206. }
  207. bool CpuProfiler::Start(const char* fname, const ProfilerOptions* options) {
  208. SpinLockHolder cl(&lock_);
  209. if (collector_.enabled()) {
  210. return false;
  211. }
  212. ProfileHandlerState prof_handler_state;
  213. ProfileHandlerGetState(&prof_handler_state);
  214. ProfileData::Options collector_options;
  215. collector_options.set_frequency(prof_handler_state.frequency);
  216. if (!collector_.Start(fname, collector_options)) {
  217. return false;
  218. }
  219. filter_ = NULL;
  220. if (options != NULL && options->filter_in_thread != NULL) {
  221. filter_ = options->filter_in_thread;
  222. filter_arg_ = options->filter_in_thread_arg;
  223. }
  224. // Setup handler for SIGPROF interrupts
  225. EnableHandler();
  226. return true;
  227. }
  228. CpuProfiler::~CpuProfiler() {
  229. Stop();
  230. }
  231. // Stop profiling and write out any collected profile data
  232. void CpuProfiler::Stop() {
  233. SpinLockHolder cl(&lock_);
  234. if (!collector_.enabled()) {
  235. return;
  236. }
  237. // Unregister prof_handler to stop receiving SIGPROF interrupts before
  238. // stopping the collector.
  239. DisableHandler();
  240. // DisableHandler waits for the currently running callback to complete and
  241. // guarantees no future invocations. It is safe to stop the collector.
  242. collector_.Stop();
  243. }
  244. void CpuProfiler::FlushTable() {
  245. SpinLockHolder cl(&lock_);
  246. if (!collector_.enabled()) {
  247. return;
  248. }
  249. // Unregister prof_handler to stop receiving SIGPROF interrupts before
  250. // flushing the profile data.
  251. DisableHandler();
  252. // DisableHandler waits for the currently running callback to complete and
  253. // guarantees no future invocations. It is safe to flush the profile data.
  254. collector_.FlushTable();
  255. EnableHandler();
  256. }
  257. bool CpuProfiler::Enabled() {
  258. SpinLockHolder cl(&lock_);
  259. return collector_.enabled();
  260. }
  261. void CpuProfiler::GetCurrentState(ProfilerState* state) {
  262. ProfileData::State collector_state;
  263. {
  264. SpinLockHolder cl(&lock_);
  265. collector_.GetCurrentState(&collector_state);
  266. }
  267. state->enabled = collector_state.enabled;
  268. state->start_time = static_cast<time_t>(collector_state.start_time);
  269. state->samples_gathered = collector_state.samples_gathered;
  270. int buf_size = sizeof(state->profile_name);
  271. strncpy(state->profile_name, collector_state.profile_name, buf_size);
  272. state->profile_name[buf_size-1] = '\0';
  273. }
  274. void CpuProfiler::EnableHandler() {
  275. RAW_CHECK(prof_handler_token_ == NULL, "SIGPROF handler already registered");
  276. prof_handler_token_ = ProfileHandlerRegisterCallback(prof_handler, this);
  277. RAW_CHECK(prof_handler_token_ != NULL, "Failed to set up SIGPROF handler");
  278. }
  279. void CpuProfiler::DisableHandler() {
  280. RAW_CHECK(prof_handler_token_ != NULL, "SIGPROF handler is not registered");
  281. ProfileHandlerUnregisterCallback(prof_handler_token_);
  282. prof_handler_token_ = NULL;
  283. }
  284. // Signal handler that records the pc in the profile-data structure. We do no
  285. // synchronization here. profile-handler.cc guarantees that at most one
  286. // instance of prof_handler() will run at a time. All other routines that
  287. // access the data touched by prof_handler() disable this signal handler before
  288. // accessing the data and therefore cannot execute concurrently with
  289. // prof_handler().
  290. void CpuProfiler::prof_handler(int sig, siginfo_t*, void* signal_ucontext,
  291. void* cpu_profiler) {
  292. CpuProfiler* instance = static_cast<CpuProfiler*>(cpu_profiler);
  293. if (instance->filter_ == NULL ||
  294. (*instance->filter_)(instance->filter_arg_)) {
  295. void* stack[ProfileData::kMaxStackDepth];
  296. // Under frame-pointer-based unwinding at least on x86, the
  297. // top-most active routine doesn't show up as a normal frame, but
  298. // as the "pc" value in the signal handler context.
  299. stack[0] = GetPC(*reinterpret_cast<ucontext_t*>(signal_ucontext));
  300. // We skip the top three stack trace entries (this function,
  301. // SignalHandler::SignalHandler and one signal handler frame)
  302. // since they are artifacts of profiling and should not be
  303. // measured. Other profiling related frames may be removed by
  304. // "pprof" at analysis time. Instead of skipping the top frames,
  305. // we could skip nothing, but that would increase the profile size
  306. // unnecessarily.
  307. int depth = GetStackTraceWithContext(stack + 1, arraysize(stack) - 1,
  308. 3, signal_ucontext);
  309. void **used_stack;
  310. if (depth > 0 && stack[1] == stack[0]) {
  311. // in case of non-frame-pointer-based unwinding we will get
  312. // duplicate of PC in stack[1], which we don't want
  313. used_stack = stack + 1;
  314. } else {
  315. used_stack = stack;
  316. depth++; // To account for pc value in stack[0];
  317. }
  318. instance->collector_.Add(depth, used_stack);
  319. }
  320. }
  321. #if !(defined(__CYGWIN__) || defined(__CYGWIN32__))
  322. extern "C" PERFTOOLS_DLL_DECL void ProfilerRegisterThread() {
  323. ProfileHandlerRegisterThread();
  324. }
  325. extern "C" PERFTOOLS_DLL_DECL void ProfilerFlush() {
  326. CpuProfiler::instance_.FlushTable();
  327. }
  328. extern "C" PERFTOOLS_DLL_DECL int ProfilingIsEnabledForAllThreads() {
  329. return CpuProfiler::instance_.Enabled();
  330. }
  331. extern "C" PERFTOOLS_DLL_DECL int ProfilerStart(const char* fname) {
  332. return CpuProfiler::instance_.Start(fname, NULL);
  333. }
  334. extern "C" PERFTOOLS_DLL_DECL int ProfilerStartWithOptions(
  335. const char *fname, const ProfilerOptions *options) {
  336. return CpuProfiler::instance_.Start(fname, options);
  337. }
  338. extern "C" PERFTOOLS_DLL_DECL void ProfilerStop() {
  339. CpuProfiler::instance_.Stop();
  340. }
  341. extern "C" PERFTOOLS_DLL_DECL void ProfilerGetCurrentState(
  342. ProfilerState* state) {
  343. CpuProfiler::instance_.GetCurrentState(state);
  344. }
  345. #else // OS_CYGWIN
  346. // ITIMER_PROF doesn't work under cygwin. ITIMER_REAL is available, but doesn't
  347. // work as well for profiling, and also interferes with alarm(). Because of
  348. // these issues, unless a specific need is identified, profiler support is
  349. // disabled under Cygwin.
  350. extern "C" void ProfilerRegisterThread() { }
  351. extern "C" void ProfilerFlush() { }
  352. extern "C" int ProfilingIsEnabledForAllThreads() { return 0; }
  353. extern "C" int ProfilerStart(const char* fname) { return 0; }
  354. extern "C" int ProfilerStartWithOptions(const char *fname,
  355. const ProfilerOptions *options) {
  356. return 0;
  357. }
  358. extern "C" void ProfilerStop() { }
  359. extern "C" void ProfilerGetCurrentState(ProfilerState* state) {
  360. memset(state, 0, sizeof(*state));
  361. }
  362. #endif // OS_CYGWIN
  363. // DEPRECATED routines
  364. extern "C" PERFTOOLS_DLL_DECL void ProfilerEnable() { }
  365. extern "C" PERFTOOLS_DLL_DECL void ProfilerDisable() { }