导航:[首页]->[other]->[Google CpuProfiler在x64 Linux下的问题]

Google出品的gperftools cpu profiler程序,以其良好的支持多线程、动态库等一系列亮点广受欢迎,不过最近在x64 Linux下却怎么都取样不了。于是发现了个tip需要注意。

原文如下

https://code.google.com/p/gperftools/source/browse/INSTALL

*** NOTE FOR 64-BIT LINUX SYSTEMS

The glibc built-in stack-unwinder on 64-bit systems has some problems
with the perftools libraries.  (In particular, the cpu/heap profiler
may be in the middle of malloc, holding some malloc-related locks when
they invoke the stack unwinder.  The built-in stack unwinder may call
malloc recursively, which may require the thread to acquire a lock it
already holds: deadlock.)

For that reason, if you use a 64-bit system, we strongly recommend you
install libunwind before trying to configure or install gperftools.
libunwind can be found at

   http://download.savannah.gnu.org/releases/libunwind/libunwind-0.99-beta.tar.gz

Even if you already have libunwind installed, you should check the
version.  Versions older than this will not work properly; too-new
versions introduce new code that does not work well with perftools
(because libunwind can call malloc, which will lead to deadlock).

There have been reports of crashes with libunwind 0.99 (see
http://code.google.com/p/gperftools/issues/detail?id=374).
Alternately, you can use a more recent libunwind (e.g. 1.0.1) at the
cost of adding a bit of boilerplate to your code.  For details, see
http://groups.google.com/group/google-perftools/msg/2686d9f24ac4365f

   CAUTION: if you install libunwind from the url above, be aware that
   you may have trouble if you try to statically link your binary with
   perftools: that is, if you link with 'gcc -static -lgcc_eh ...'.
   This is because both libunwind and libgcc implement the same C++
   exception handling APIs, but they implement them differently on
   some platforms.  This is not likely to be a problem on ia64, but
   may be on x86-64.

   Also, if you link binaries statically, make sure that you add
   -Wl,--eh-frame-hdr to your linker options. This is required so that
   libunwind can find the information generated by the compiler
   required for stack unwinding.

   Using -static is rare, though, so unless you know this will affect
   you it probably won't.

If you cannot or do not wish to install libunwind, you can still try
to use the built-in stack unwinder.  The built-in stack unwinder
requires that your application, the tcmalloc library, and system
libraries like libc, all be compiled with a frame pointer.  This is
*not* the default for x86-64.

If you are on x86-64 system, know that you have a set of system
libraries with frame-pointers enabled, and compile all your
applications with -fno-omit-frame-pointer, then you can enable the
built-in perftools stack unwinder by passing the
--enable-frame-pointers flag to configure.

Even with the use of libunwind, there are still known problems with
stack unwinding on 64-bit systems, particularly x86-64.  See the
"64-BIT ISSUES" section in README.

If you encounter problems, try compiling perftools with './configure
--enable-frame-pointers'.  Note you will need to compile your
application with frame pointers (via 'gcc -fno-omit-frame-pointer
...') in this case.

https://code.google.com/p/gperftools/source/browse/README

CPU PROFILER
------------
See doc/cpu-profiler.html for information about how to use the CPU
profiler and analyze its output.

As a quick-start, do the following after installing this package:

1) Link your executable with -lprofiler
2) Run your executable with the CPUPROFILE environment var set:
     $ CPUPROFILE=/tmp/prof.out <path/to/binary> [binary args]
3) Run pprof to analyze the CPU usage
     $ pprof <path/to/binary> /tmp/prof.out      # -pg-like text output
     $ pprof --gv <path/to/binary> /tmp/prof.out # really cool graphical output

There are other environment variables, besides CPUPROFILE, you can set
to adjust the cpu-profiler behavior; cf "ENVIRONMENT VARIABLES" below.

The CPU profiler is available on all unix-based systems we've tested;
see INSTALL for more details.  It is not currently available on Windows.

NOTE: CPU profiling doesn't work after fork (unless you immediately
      do an exec()-like call afterwards).  Furthermore, if you do
      fork, and the child calls exit(), it may corrupt the profile
      data.  You can use _exit() to work around this.  We hope to have
      a fix for both problems in the next release of perftools
      (hopefully perftools 1.2).

其中有几点:

  1. 最好是安装libunwind,并且不要最新版本
  2. configure gperftools时。添加--enable-frame-pointers选项,同时在编译目标程序时,添加-fno-omit-frame-pointer选项
  3. 避免fork(大多数后台都会将其变成后台进程,这其中就会fork)