We've a backtrace for a segfault that quotes a compiler-generated name for a lambda:
(gdb) bt
#0 std::_Function_handler<std::function<bool()>(), bold::AdHocOptionTreeBuilder::buildTree(bold::Agent*)::__lambda59>::_M_invoke(const std::_Any_data &) (__functor=...) at /usr/include/c++/4.8/functional:2057
#1 0x08146d2c in operator() (this=<optimized out>) at /usr/include/c++/4.8/functional:2464
...
The assigned name is bold::AdHocOptionTreeBuilder::buildTree(bold::Agent*)::__lambda59. However as you can tell that file has a lot of lambda in it! Is there a way to map that generated function's name to a line number in the source code? We have line numbers for other functions, however here it's only quoted as a type param for std::_Function_handler<>.
The linker option -Map mapfile should give you the information showing where each function originated, including lambda's. nm --line-numbers might work too, if the program was compiled with debug info -g.
Also, I think you can use set print symbol-filename on in GDB, and then evaluate &bold::AdHocOptionTreeBuilder::buildTree(bold::Agent*)::__lambda59
Related
I often get stack traces from libunwind or AddressSanitizer like this:
#12 0x7ffff4b47063 (/home/janw/src/pl-devel/lib/x86_64-linux/libswipl.so.7.1.13+0x1f5063)
#13 0x7ffff4b2c783 (/home/janw/src/pl-devel/lib/x86_64-linux/libswipl.so.7.1.13+0x1da783)
#14 0x7ffff4b2cca4 (/home/janw/src/pl-devel/lib/x86_64-linux/libswipl.so.7.1.13+0x1daca4)
#15 0x7ffff4b2cf42 (/home/janw/src/pl-devel/lib/x86_64-linux/libswipl.so.7.1.13+0x1daf42)
I know that if I have gdb attached to the still living process, I can use this to get details
on the location:
(gdb) list *0x7ffff4b47063
But if the process has died, I can not just restart it under gdb and use the above because
address randomization makes that I get the wrong result (at least, that is my assumption;
I clearly do not get meaningful locations). So, I tried
% gdb program
% run
<get to the place everything is loaded and type Control-C>
(gdb) info shared
<Dumps mapping location of shared objects>
(gdb) list *(<base of libswipl.so.7.1.13>+0x1f5063)
But, this either lists nothing or clearly the wrong location. This sounds simple, but
I failed to find the answer :-( Platform is 64-bit Linux, but I guess this applies to
any platform.
(gdb) info shared
<Dumps mapping location of shared objects>
Unfortunately, above does not dump actual mapping location that is usable with this:
libswipl.so.7.1.13+0x1f5063
(as you've discovered). Rather, GDB output lists where the .text section was mapped, not where the ELF binary itself was mapped.
You can adjust for .text offset by finding it in
readelf -WS libswipl.so.7.1.13 | grep '\.text'
It might be easier to use addr2line instead. Something like
addr2line -fe libswipl.so.7.1.13 0x1f5063 0x1da783
should work.
Please see http://clang.llvm.org/docs/AddressSanitizer.html for the instructions on using the asan_symbolize.py script and/or the symbolize=true option.
In GDB, the command:
list function
will list all the source for the function.
Is there a command that will list all of the source of the function you are currently in, without requiring you to manually type the function name?
(gdb) help list
List specified function or line.
With no argument, lists ten more lines after or around previous listing.
"list -" lists the ten lines before a previous ten-line listing.
One argument specifies a line, and ten lines are listed around that line.
Two arguments with comma between specify starting and ending lines to list.
Lines can be specified in these ways:
LINENUM, to list around that line in current file,
FILE:LINENUM, to list around that line in that file,
FUNCTION, to list around beginning of that function,
FILE:FUNCTION, to distinguish among like-named static functions.
*ADDRESS, to list around the line containing that address.
With two args if one is empty it stands for ten lines away from the other arg.
The *ADDRESS is what is interesting.
On x86/x64 current pointer is in rip register so:
(gdb) list *$pc
0x7ffff7b018a0 is at ../sysdeps/unix/syscall-template.S:82.
77 in ../sysdeps/unix/syscall-template.S
The example is from cat command as I don't have anything with debug info at hand.
When you are stopped in a function type bt for backtrace.
Backtrace will list the current stack. The element at the top, #0, is usually the function you are interested in and the source file and line number is listed also.
For example:
(gdb) bt
#0 myClass::EntityTypeStruct::readAttributes (this=0x7fffd00066e0, buf=0x7fffd0006020 "", len=48)
at /team/project/src/EntityTypeStruct.cc:55
#1 0x000000000044ca86 in workerThread (ts=0x7fffea71dcc0)
at /team/project/src/threads/workerThread.cc:219
#2 0x00007ffff775e9d1 in start_thread () from /lib64/libpthread.so.0
#3 0x00007ffff6c07b5d in clone () from /lib64/libc.so.6
See http://www.chemie.fu-berlin.de/chemnet/use/info/gdb/gdb_7.html#SEC42 for more info.
Also, when you set a breakpoint you can specify commands that will run everytime you hit that breakpoint. See http://www.chemie.fu-berlin.de/chemnet/use/info/gdb/gdb_6.html#SEC35
So, if you know how many lines are in your function you could set a command to list all source lines of the function:
(gdb) break myClass::EntityTypeStruct::readAttributes
Breakpoint 1 at 0x61ec3b: file /team/project/src/EntityTypeStruct.cc, line 38.
(gdb) commands 1
list 38,104
end
gdbtui can be useful to view the source during debugging.
The 'frame' command shows the function name and the current line location and sets the current line for list to the current executable line.
set listsize 17
frame
list
lists the 8 lines surrounding the current line.
My gdb bt callstack gives function name with function address. Then I did nm binary
and generated the function name and address mapping. When I tried to match gdb address with nm output it did not match. The function address in (gdb) bt where too high (looks like physical address).
gdb function address (e.g 0x00007fffe6fc150f):
#9 0x00007fffe6fc150f in read_alias_file (fname=<value optimized out>, fname_len=<value optimized out>) at localealias.c:224
#10 0x00007fffe6fc1a4e in _nl_expand_alias (name=0x7fffffffed04 "en_IN") at localealias.c:189
#11 0x00007fffe6fbb62f in _nl_find_locale (locale_path=0x7fffe70df580 "/usr/lib/locale", locale_path_len=16, category=12, name=0x7fffffffdb90) at findlocale.c:119
#12 0x00007fffe6fbacf6 in *__GI_setlocale (catesagory=12, locale=<value optimized out>) at setlocale.c:303
#13 0x00007ffff17b8686 in
but when I did nm the address from the binary I got is like this
0000000005ddda04 t StubGLBindFragDataLocationIndexed
0000000005ddda3f t StubGLBindFramebuffer
0000000005ddda65 t StubGLBindRenderbuffer
0000000005ddda8b t StubGLBindTexture
0000000005dddab1 t StubGLBlendColor
0000000005dddaef t StubGLBlendFunc
0000000005dddb15 t StubGLBlitFramebuffer
0000000005dddb7e t StubGLBufferData
0000000005dddbbd t StubGLBufferSubData
0000000005dddc00 t StubGLCheckFramebufferStatus
0000000005dddc1e t StubGLClear
0000000005dddc3c t StubGLClearColor
0000000005dddc7a t StubGLClearStencil
0000000005dddc98 t StubGLColorMask
0000000005dddcda t StubGLCompileShader
The Machine is 64 bit.
As i know the gdb shows only virtual address. But I dont know why it is coming so high and
doesnot match with address present nm output
Is the gdb address are virtual address??. nm o/p looks like actual virtual address since it starts from 000000000. But then why base address are added automatically?
Note: I tried with sample test.out. that works fine. The bt callstack address are virtual address and perfectly matches with nm a.out symbols output.
The 0x00007fffe6fc150f address is coming from a shared library (libc.so.6 in this case). It is the virtual address, but it will not match output from nm /lib/libc.so.6 because the library is loaded at certain load address, which varies from execution to execution.
You can find out when libc.so.6 is loaded by executing info proc map GDB command. Once you know the load address for libc.so.6, add it to every address in nm output, and the result will match GDB output.
The reason this worked for a simple a.out is that (unlike shared libraries) a.out is linked to be loaded at a fixed load address (usually 0x400000 on Linux x86_64), and is not relocated by the dynamic loader.
We have a binary that generates coredump. So I ran the gdb command to analyze the issue. Please note the binary and code are in two different locations and we cannot build the whole binary using debugging symbols. Hence how and what details can I find from below backtarce:
gdb binary corefile
(gdb) where
#0 0x101fa37a in f1()
#1 0x10203812 in operator f2< ()
#2 0x085f6244 in f3 ()
#3 0x085f1574 in f4()
#4 0x0805b27b in sigsegv_handler ()
#5 <signal handler called>
#6 0x1018d945 in f5()
#7 0x1018e021 in f6()
..................................
#29 0x08055c5c in main ()
(gdb)
Please provide me gdb commands that I can issue to find what’s data inside each stack frame, what’s the issue probably is, where it is failing, other debugging methods if any?
You can use help in gdb. To navigate the stack : help stack
The main useful commands to navigate the stack are up and down. If you have debugging symbols at hand, you can use list to see where you are. Then to get information, you need print (abbreviated as 'p'). For example, if you have an int called myInt then you just type p myInt. With no debug info it will be harder. From your stack frame it seems that the problem is in f5(). One thing you can do is start your program inside gdb. it will stop right where the segfault happens. When you have hints about the part of your code that segfaults, you can compile this code unit with debugging options.
That the basics. Tell us more if you want more help.
my2c
I'd like to go through a binary file my teacher gave me line by line to check addresses on the stack and the contents of different registers, but I'm not extremely familiar with using gdb. Although I have the C code, we're supposed to work entirely from a binary file. Here are the commands I've used so far:
(gdb) file SomeCode
Which gives me this message:
Reading symbols from ../overflow/SomeCode ...(no debugging symbols found)...done.
Then I use :
(gdb) disas main
which gives me all of the assembly. I wanted to set up a break point and use the "next" command, but none of the commands I tried work. Does anyone know the syntax I would use?
try using ni which is nexti. equivalent is si which is step instruction
nexti if you want to jump over function calls.
stepi if you want to enter a function call.
The following documentation is very helpful; it has a list of all the important commands you could use on gdb.
X86-64: http://csapp.cs.cmu.edu/public/docs/gdbnotes-x86-64.pdf
IA32: http://csapp.cs.cmu.edu/public/docs/gdbnotes-ia32.pdf