I am trying to learn profiling with GNU gprof, and I just tried to take the same results as in this tutorial by using exactly the same code and applying the same steps there: http://www.ibm.com/developerworks/library/l-gnuprof.html
However, when I try to reach flat profile by gprof example1 gmon.out -p, what I see nothing. It says
Each sample counts as 0.01 seconds. no time accumulated
and I am seeing an empty flat profile. And when I try to obtain call graph, I receive
gprof: gmon.out file is missing call-graph data
I am using Ubuntu on a VirtualBox VM. May using VirtualBox be the reason?
Related
I'm using a Blue Pill board (STM32F103CB with 128kB of flash according to st-info --probe) via a clone ST-Link/V2 like this one. I've also tested using a genuine ST-Link/V2 like this one. I get the same result, described below, with both programmers.
My system is Linux (Debian LXDE) and I've installed OpenOCD from Liviu Ionescu's releases here.
My OpenOCD installation is working. As well as the Blue Pill I have a ST-Nucleo-F103RB board, and I can connect to it using OpenOCD. The command
openocd -f board/st_nucleo_f103rb.cfg
using the standard .cfg file that ships with OpenOCD gives
Open On-Chip Debugger 0.10.0
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
adapter speed: 1000 kHz
adapter_nsrst_delay: 100
none separate
srst_only separate srst_nogate srst_open_drain connect_deassert_srst
Info : Unable to match requested speed 1000 kHz, using 950 kHz
Info : Unable to match requested speed 1000 kHz, using 950 kHz
Info : clock speed 950 kHz
Info : STLINK v2 JTAG v29 API v2 SWIM v18 VID 0x0483 PID 0x374B
Info : using stlink api v2
Info : Target voltage: 3.271135
Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints
But I still haven't managed to connect to my Blue Pill using the ST-Link/V2 programmers. I've read everything I can find, including relevant sections of https://elinux.org/Category:OpenOCD and as much as I can personally digest of http://openocd.org/doc/. The following is where I've got to.
The .cfg file stm32f103c8_blue_pill.cfg doesn't work for me. It produces the output described below.
Based on what I've read I've prepared my own .cfg file at ../board/stm32f103.cfg. It says:
source [find interface/stlink.cfg]
transport select hla_swd
source [find target/stm32f1x.cfg]
#source [find board/stm32f103c8_blue_pill.cfg]
#reset_config srst_only
#reset_config none separate
Sources I've read suggest this should work, but it doesn't. Using my .cfg described above, it I can use either target/stm32f1x.cfg or board/stm32f103c7_blue_pill.cfg, and I still get the same output as described below. (In the case of both of those .cfg files I'm using the standard files, as shipped with OpenOCD.) I've tested with both of the reset_config variants shown above, and with neither. None of the combinations works.
The file interface/stlink.cfg that I'm using is modified. I've changed it to state the correct device_desc "ST-LINK/V2" and the correct vid_pid 0x0483 0x3748. (Both confirmed using lsusb.) So, ignoring commented lines, stlink.cfg reads
interface hla
hla_layout stlink
hla_device_desc "ST-LINK/V2"
hla_vid_pid 0x0483 0x3748
I've experimented with including the hla_serial of the programmer. Interestingly, lsusb can't find the full serial number. st-info --probe finds the serial number, but gives a slightly different number from the STLinkUpgrade firmware application. I've tried using both serial numbers. No difference.
Here's the command I give to OpenOCD:
openocd -s ~/stm32/openocd/scripts -f board/stm32f103.cfg
Notice that I have to set the path using -s for this command. With the ST-Nucleo-F103RB board, I don't have to do this. With the stm32f103.cfg file, however, if I don't set the path I get:
Error: Can't find board/stm32f103.cfg
in procedure 'script'
If I use the full command shown above, with -s to set the path, I get:
Open On-Chip Debugger 0.10.0
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
/[..]stm32/openocd/scripts/target/stm32f1x.cfg:47: Error: invalid command name "dap"
in procedure 'script'
at file "embedded:startup.tcl", line 60
at file "/[..]stm32/openocd/scripts/board/stm32f103.cfg", line 18
at file "/[..]stm32/openocd/scripts/target/stm32f1x.cfg", line 47
Here's the offending line 47 of stm32f1x.cfg:
dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
I've searched for items on Stackoverflow/ similar about Error: invalid command name "dap". Using the OpenOCD documentation I understand that the dap create command exists, and roughly what it does. The most similar reported error I've found documented is at https://elinux.org/OpenOCD_Troubleshooting:_Invalid_Command_Name_JTAG, and the solution suggested there doesn't seem to be applicable because I'm not invoking interface/stlink.cfg from the command line.
I can't see what I'm doing wrong, and I'm now completely stuck. If someone can give me a steer I'd be really grateful. Sorry it's such a long post.
I just encountered this problem too. Officially there are no binaries provided, only source code. But there are two sites which release binaries was recommended by OpenOCD official:
1. Maintained by Freddie Chopin.
2. Maintained by Liviu Ionescu in Github.
I tried the latest version(OpenOCD 0.10.0 commit date: 2017-01-22 20:31:28 build date: 2017-01-23) released from Freddie Chopin's site, and I encountered this Error: invalid command name "dap" problem. But all *.cfg files I referenced had ran normally in my another computer with another OpenOCD binary(although I forgot where did I download that binary).
Not sure what went wrong, so I turned to the latest version(gnu-mcu-eclipse-openocd-0.10.0-11-20190118-1134-win64.zip) released by GNU MCU Eclipse(maintained by Liviu Ionescu), the error was gone, problem solved.
PS: I'm not saying there is a bug in Freddie Chopin's build, but if someone encountered this problem, maybe you can solve it by trying the version which is currently under actively maintained.
Agree with Wulfric, using standard install for OpenOCD
sudo apt install openocd
gave the "dap" error.
However the github version openocd-xpack worked correctly.
Using:
Linux clamps 4.15.0-66-generic #75-Ubuntu SMP ... as remote, Windows 8/10 as client target MIMXRT1010-EVK
I'm using callgrind to profile a small piece of code. Callgrind output files are well generated, their content looks ok, but I'm unable to open them with kcachegrind: I get the following error message:
Could not open file "callgrind.out.4953". Check it exists and you have enough permissions to read it.
I have all permissions on files and directories they are in, but with the same issue. Also, it works well with an other project, in an other folder in the same workspace. I also precise that the processes terminate correctly in both cases.
I recently reported to the kcachegrind developer a problem with exactly the same symptoms. The problem is triggered when callgrind is used with a very long command line. This was fixed in the next versions of valgrind/callgrind and kcachegrind.
Find below the commit log for the valgrind side.
Waiting for the new releases of valgrind and kcachegrind, if your problem
is also due to a too long command line, you can just edit the file and truncate the cmd: line.
If your problem is not the length of the cmd line, then I guess you will need to use callgrind_annotate (if this work) or further investigate why kcachegrind finds your file problematic.
Author: weidendo Date: Tue Jan 10 20:21:21 2017 New Revision: 16196
Log: Add a format marker to callgrind files
KCachegrind currently uses a quick format detection before actually
loading a file, and checks for a line starting with "events:" in the
first 2kB for that. This obviously is fragile, as shown by an internal
bug report by Philippe: before the "events" line, Callgrind puts a
"cmd:" line with the command line. If this is very long, the detection
fails and the file does not get loaded at all.
While KCachegrind would not need to have this quick format check at
all, it is useful if multiple input format filters get supported at
some point, to automatically select the correct filter.
Further, for the "file" command, for file managers and desktop
environments, having an unique way to detect a file format is
important.
It is not too late to fix this issue for the callgrind format.
I have found several conflicting answers over this topic. This blog post requires libuwind, but that doesn't work on Mac OS X. I included #include <google/profiler.h> in my code, however my compiler (g++) could not find the library. I installed gperftools via homebrew. In addition, I found this stackoverflow question showing this:
Then I ran pprof to generate the output:
[hidden ~]$ pprof --text ./a.out cpu.profile
Using local file ./a.out.
Using local file cpu.profile.
Removing __sigtramp from all stack traces.
Total: 282 samples
107 37.9% 37.9% 107 37.9% 0x000000010d72229e
16 5.7% 43.6% 16 5.7% 0x000000010d721a5f
12 4.3% 47.9% 12 4.3% 0x000000010d721de8
...
Running that command (without any of the prior steps) gets me this:
[hidden]$ pprof --text ./a.out cpu.profile
Using remote profile at ./a.out.
Failed to get the number of symbols from http://cpu.profile/pprof/symbol
Why does it try to access an internet site on my machine and a local file on his/hers?
Attempting to link lib profiler as a dry run with g++ gets me:
[hidden]$ g++ -l libprofiler
ld: library not found for -llibprofiler
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I have looked at the man pages, the help option text, the official online guide, blog posts, and many other sources.
I am so confused right now. Can someone help me use gperftools?
The result of my conversation with #osgx was this script. I tried to clean it up a bit. It likely contains quite a few unnecessary options too.
The blog post https://dudefrommangalore.wordpress.com/2012/02/09/profiling-c-code-using-google-performance-tools/ "Profiling C++ code using Google Performance Tools" 2012 by dudefrommangalore missed the essential step.
You should link your program (which you want to be profiled) with cpu profiler library of gperftools library.
Check official manual: http://goog-perftools.sourceforge.net/doc/cpu_profiler.html, part "Linking in the Library"
add -lprofiler to the link-time step for your executable. (It's also probably possible to add in the profiler at run-time using LD_PRELOAD, but this isn't necessarily recommended.)
Second step is to collect the profile, run the code with profiling enabled. In linux world it was done by setting controlling environment variable CPUPROFILE before running:
CPUPROFILE=name_of_profile ./program_to_be_profiled
Third step is to use pprof (google-pprof in ubuntu world). Check that there is not-empty name_of_profile profile file generated; it there is no such file, pprof will try to do remote profile fetch (you see output of such try).
pprof ./program_to_be_profiled name_of_profile
First you need to run your program with profiling enabled.
This is usually first linking your program with libprofiler and then running it with CPUPROFILE=cpu.profile.
I.e.
$ CPUPROFILE=cpu.profile my_program
I think that later step is what you have been missing.
The program will create this cpu.profile file when it exits. And then you can use pprof (preferably from github.com/google/pprof) on it to visualize/analyze.
I'm trying to use "perf" to see what's using all the CPU in my C++ program on Linux. I want to attach to a running process and get a list of symbols or line numbers that I can then go look at to optimize.
To attach to a process and see live updates of hotspots:
perf top -p $(pidof yourapp)
To attach to a process, then analyse it for later evaluation, do:
perf record -p $(pidof yourapp)
And later:
perf report
For both, top and record, you can add --call-graph dwarf for dwarf-based callgraphs.
Note that you should compile your application with something like -O2 -g to get optimizations and debug symbols, otherwise you won't know functions names, files, line numbers etc. pp.
I'm trying to profile a C++ application, that I did not write, to get a sense for where the major computation points are. I'm not a C++ expert and even less so C++ debugging/profiling expert. I believe I am running into a (common?) problem with dynamic libraries.
I compile link to Google CPU Profiler using (OS X, G++):
env LIBS=-lprofiler ./configure
make
make install
I then run profile the installed application (jags) with:
env CPUPROFILE=./jags.prof /usr/local/bin/jags regression.cmd
pprof /usr/local/bin/jags jags.prof
Unfortunately, I get the error:
pprof /usr/local/bin/jags jags.prof Can't exec "objdump":
No such file or directory at /usr/local/bin/pprof line 2833.
objdump /System/Library/Frameworks/Accelerate.framework/Versions/A/
Frameworks/vecLib.framework/Versions/A/libLAPACK.dylib: No such file or directory
The program dynamically links to libLAPACK.dylib. So prof does not seem to understand it (?). I thought about trying to statically link, but the documents associated with the program say that it is impossible to statically link in LAPACK or BLAS (two required libraries).
Is there a way to have the profiler ignore libLAPACK? I'm okay if it doesn't sample within libLAPACK. Or how might I get profiling to work?
This error was caused by jags being a shell script, that subsequently called profilable code.
pprof /usr/local/bin/REAL_EXEC jags.prof
fixes the problem.
I don't see a clean way to do it, but maybe there's a hacky workaround -- what happens if you hack the pprof perl script (or better a copy thereof;-), line 2834, so that instead of calling error it emits the message and then does return undef;?
If you're profiling on OSX, the Shark tool is really great as well. It's very simple to use, and has worked out of the box for me when I've tried it.