I would like to use gcc's gprof line-by-line profiling. But after compiling my program, running it and executing gprof -l binary_name I get messages like:
gprof: somebody miscounted: ltab.len=9403 instead of 9391
gprof binary_name runs without error but I have not been able to run with the -l option. I was not able to find documentation on this. Google autocomplete indicates I am not the first to get this error but I could not find any threads on it. I have tried g++-9 g++-10 and g++-11. I have tried compiling with -g and -ggdb. I considered that maybe gprof did not like my program being multithreaded but even removing the OpenMP dependency and telling libtorch to use 1 thread I get the same behavior.
I have the suspicion that this error was not meant to be seen by the end user as it gives no hints on resolution and mentions ltab.len which is most likely a variable in gcc code no user would be familiar with.
Related
I am debugging in a recompile-debug cycle that looks as follows:
Compile binary
Run debugger gdb prog
Find an error and fix the source
Exit debugger with pressing ctrl+d or typing quit
I would like to add Valgrind in the workflow to break as soon as I faced incorrect out-of-range memory read or write. I found that if I follow the officially documented process of running Valgrind with gdb I have to perform a lot more time-consuming steps.
Compile binary
Run valgrind valgrind --vgdb=yes --vgdb-error=0 prog
Open new terminal window and type gdb prog
Run target remote | vgdb (or, even worse, copy-paste command for connection printed in valgrind window if I am running multiple debug sessions)
Find an error and fix the source
Exit debugger
Kill application with valgrind process with kill -9 (because Valgrind doesn't stops it on gdb exit)
How I can automate these 3 extra steps? Ideally, I would expect to have a command like mygdb as a drop-in replacement for gdb that runs Valgrind under the hood, maybe debug slower, but breaks as soon as Valgrind detects an error.
--vgdb-error=0 indicates to valgrind to stop before it starts executing your program, so that you can connect with GDB and e.g. put breakpoints.
But if you only want to debug once an error is detected, rather give --vgdb-error=1.
With this, as long as valgrind reports no error, there is no need to do the 3 steps in bold, as valgrind will run your program till the end and exit.
When valgrind stops when encountering an error, you have to start a gdb.
You could write a shell script to automate part of the other commands e.g.
gdb -ex 'target remote | vgdb'
This script can extract the vgdb command from a log file output or any other way.
You could also define in your .gdbinit a command such as
define vquit
kill
quit
end
and use vquit instead of quit.
You can also define a gdb command to directly start your application under valgrind and connect gdb to it, e.g. something like:
define vrun
shell valgrind --vgdb-error=0 $arg0 &
target remote | vgdb --wait=10
continue
end
and then inside gdb, you can do:
(gdb) vrun your_application
How I can automate these 3 extra steps?
Not a direct answer to your question, but your entire approach is likely wrong.
You should not use the debugger to tell you about bugs; use unit tests instead. Your cycle should be make && make check.
It also helps to write the test before implementing any new functionality (see test-driven development). The test will fail, and then you'll make it succeed by implementing the new feature.
In addition, you should get into the habit of running all of your tests with the Address and Memory Sanitizers (which together catch many more bugs than valgrind does).
Finally, valgrind report itself usually provides sufficient info to understand the bug. Valgrind's integration with GDB is there for rare cases where the error report is hard to understand without looking at the values of locals, parameters, etc.
I've seen this post that tells how to get gcc to compile from standard input (type file.c | gcc -x c -):
Is it possible to get GCC to read from a pipe?
But it does not work on windows 10. I always get "The system cannot find the file specified" in spite of having tried it every way I can imagine.
Anyone know the trick?
And I can't change the version of gcc we're using (I've heard standard input compile with gcc in mingw works on windows).
My own example works just fine. It was my mistake!
Context:
go 1.2, ubuntu 12.10
Goal:
Reduce size of compiled binaries
Currently in my build process, I run "go install" to generate the binary.
The I read from somewhere that if I pass in -w it will shrink the binary.
I tried it by passing it into the -ldflags option & my binary lost 1MB in size.
Is this -w flag documented anywhere? What does it actually do?
I then discovered the strip -s <binary> command and ran that on top of -w and got
another weight loss of 750KB ! The resulting binary runs fine. Does stripping
cause problems in any situations ?
You will get the smallest binaries if you compile with -ldflags '-w -s'.
The -w turns off DWARF debugging information: you will not be able to use gdb on the binary to look at specific functions or set breakpoints or get stack traces, because all the metadata gdb needs will not be included. You will also not be able to use other tools that depend on the information, like pprof profiling.
The -s turns off generation of the Go symbol table: you will not be able to use go tool nm to list the symbols in the binary. strip -s is like passing -s to -ldflags but it doesn't strip quite as much. go tool nm might still work after strip -s. I am not completely sure.
None of these — not -ldflags -w, not -ldflags -s, not strip -s — should affect the execution of the actual program. They only affect whether you can debug or analyze the program with other tools.
You can get help from go tool link
$ go tool link
...
-s disable symbol table
-w disable DWARF generation
The go help build says that
-ldflags 'flag list'
arguments to pass on each 5l, 6l, or 8l linker invocation.
So, we can invoke go tool 6l to see all it's options. One of them is
-w disable DWARF generation
By the way, 5l stands for ARM ($GOARCH = arm), 6l stands for x86-64 ($GOARCH = amd64), and 8l is for x86 ($GOARCH = 386).
If you really want to view raw DWARF info you should use dwarfdump -a on OS X and objdump -wg on Linux. Warning! Output will be long, very long.
I'm afraid it might cause problems in programs compiled with Go 1.2's gc suite of tools—refer to this discussion.
The general idea is that while Go compiles down to machine code just like C, it's more higher-level than C. For instance, it has built-in detailed panic() stack traces which depend on debug info. The sizes of the gc-generated binaries could indeed have been smaller, and it might be addresseed while cooking Go 1.3, but really the size of a compiled program in most today's environments is not a big deal to be too concerned about.
Is there any gcc option I can set that will give me the line number of the segmentation fault?
I know I can:
Debug line by line
Put printfs in the code to narrow down.
Edits:
bt / where on gdb give No stack.
Helpful suggestion
I don't know of a gcc option, but you should be able to run the application with gdb and then when it crashes, type where to take a look at the stack when it exited, which should get you close.
$ gdb blah
(gdb) run
(gdb) where
Edit for completeness:
You should also make sure to build the application with debug flags on using the -g gcc option to include line numbers in the executable.
Another option is to use the bt (backtrace) command.
Here's a complete shell/gdb session
$ gcc -ggdb myproj.c
$ gdb a.out
gdb> run --some-option=foo --other-option=bar
(gdb will say your program hit a segfault)
gdb> bt
(gdb prints a stack trace)
gdb> q
[are you sure, your program is still running]? y
$ emacs myproj.c # heh, I know what the error is now...
Happy hacking :-)
You can get gcc to print you a stacktrace when your program gets a SEGV signal, similar to how Java and other friendlier languages handle null pointer exceptions. See my answer here for more details:
how to generate a stacktace when my C++ app crashes ( using gcc compiler )
The nice thing about this is you can just leave it in your code; you don't need to run things through gdb to get the nice debug output.
If you compile with -g and follow the instructions there, you can use a command-line tool like addr2line to get file/line information from the output.
Run it under valgrind.
you also need to build with debug flags on -g
You can also open the core dump with gdb (you need -g though).
If all the preceding suggestions to compile with debugging (-g) and run under a debugger (gdb, run, bt) are not working for you, then:
Elementary: Maybe you're not running under the debugger, you're just trying to analyze the postmortem core dump. (If you start a debug session, but don't run the program, or if it exits, then when you ask for a backtrace, gdb will say "No stack" -- because there's no running program at all. Don't forget to type "run".) If it segfaulted, don't forget to add the third argument (core) when you run gdb, otherwise you start in the same state, not attached to any particular process or memory image.
Difficult: If your program is/was really running but your gdb is saying "No stack" perhaps your stack pointer is badly smashed. In which case, you may be a buffer overflow problem somewhere, severe enough to mash your runtime state entirely. GCC 4.1 supports the ProPolice "Stack Smashing Protector" that is enabled with -fstack-protector-all. It can be added to GCC 3.x with a patch.
There is no method for GCC to provide this information, you'll have to rely on an external program like GDB.
GDB can give you the line where a crash occurred with the "bt" (short for "backtrace") command after the program has seg faulted. This will give you not only the line of the crash, but the whole stack of the program (so you can see what called the function where the crash happened).
The No stack problem seems to happen when the program exit successfully.
For the record, I had this problem because I had forgotten a return in my code, which made my program exit with failure code.
So I wrote buggy code that occasionally crash ... and creates a stackdump file.
Using addr2line I can figure out how the program got to the crash point by decoding the addresses from the stackdump one by one. Is there an alternative tool that can ease the debug using stack dumps?
Is there a way to to load this information in Insight/Gdb?
You can instruct Cygwin to start your gdb debugger just in time when an fault occurs.
To achieve this, add error_start=action to the Cygwin environment variable:
export CYGWIN="$CYGWIN error_start=gdb -nw %1 %2"
Else you can have Cygwin generate a real core dump.
export CYGWIN="$CYGWIN error_start=dumper -d %1 %2"
Firstly, make sure you build with source debugging enabled (the using -g option):
gcc -g -o myfile myfile.c
Then Load the dump into gdb after the crash (or insight, or ddd)
gdb myfile core