Why are there no debug symbols in my vmlinux when using gdb with /proc/kcore? - gdb

I've configure all CONFIG_DEBUG_ related options to y,but when I try to debug the kernel,it says no debug symbols found:
gdb /usr/src/linux-2.6.32.9/vmlinux /proc/kcore
Reading symbols from /usr/src/linux-2.6.32.9/vmlinux...(no debugging symbols found)...done.
Why?

Here is my best guess so far: I don't know, and it doesn't matter.
I don't know why GDB is printing the message "(no debugging symbols found)". I've actually seen this when building my own kernels. I configure a kernel to use debug symbols, but GDB still prints this message when it looks at the kernel image. I never bothered to look into it, because my image can still be debugged fine. Despite the message, GDB can still disassemble functions, add breakpoints, look up symbols, and single-step through functions. I never noticed a lack of debugging functionality. I'm guessing that the same thing is happening to you.
Edit: Based on the your comments to the question, it looks like you were searching for the wrong symbol with your debugger. System call handlers start with a prefix of sys_, but you can't tell from looking at the code. The macro SYSCALL_DEFINE4(ptrace, ...) just ends up declaring the function as asmlinkage long sys_ptrace(...), although it does some other crazy stuff if you have ftrace enabled.

make menuconfig->kernel hacking->[]Kernel debugging->[]Compile the kernel with debug info(CONFIG_DEBUG_INFO)

It's also possible when you package your vmlinuz image, the debug symbols were stripped (when using make-kpkg to build deb package for linux kernel). So you have to use the built vmlinux file under your linux source tree to have those debug symbols.

Add -g to the CFLAGS variable in the kernel Makefile

I might be wrong, but I thought you would have to install the debuginfo package for your kernel to get symbols

Related

loading libc's symbols into gdb

I'm debugging a binary with an older libc version than my system's one (I have libc-2.31, I'm running 2.24). I execute gdb with the LD_LIBRARY_PATH and it works like a charm, but I cannot load any symbols.
I downloaded the closest symbols file from http://archive.ubuntu.com/ubuntu/pool/main/g/glibc/libc6-dbg_2.23-0ubuntu11.2_amd64.deb, extracted it and after loading the binary into gdb, I execute:
add-symbol-file <path_to_libc-2.27.so from the deb package>
the file was loaded successfuly, but the addresses are incorrect. For example, trying to stop on a symbol such as 'main_arena' (x/40gx &main_arena) produces the following error:
0x3ebc40 <main_arena>: Cannot access memory at address 0x3ebc40
obviously this address is too low, thus I guess it's only the offset. What is my problem? maybe I need to find the exact debug file that suits my version (2.24)? because I there is no one.
Thanks!
I execute gdb with the LD_LIBRARY_PATH and it works like a charm,
It is not supposed to work, and if it happens to work today, it will likely break tomorrow.
The easiest solution is to debug inside a VM or a docker container with the desired version of GLIBC installed.
If you don't want to do that, see this answer on how to properly set things up for multiple GLIBCs on a single host.

Meaning of a gdb backtrace when there is not source code

I have a gdb backtrace of a crashed process, but I can't see the specific line in which the crash occurred because the source code was not in that moment. I don't understand some of the information given by the mentioned backtrace.
The backtrace is made of lines like the following one:
<path_to_binary_file>(_Z12someFunction+0x18)[0x804a378]
Notice that _Z12someFunction is the mangled name of int someFunction(double ).
My questions are:
Does the +0x18 indicate the offset, starting at _Z12someFunction address, of the assembly instruction that produced the crash?
If the previous question is affirmative, and taking into account that I am working with a 32-bit architecture, does the +0x18 indicates 0x18 * 4 bytes?
If the above is affirmative, I assume that the address 0x804a378 is the _Z12someFunction plus 0x18, am I right?
EDIT:
The error has ocurred in a production machine (no cores enabled), and it seems to be a timing-dependant bug, so it is not easy to reproduce it. That is because the information I am asking for is important to me in this occasion.
Most of your assumptions are correct. The +0x18 indeed means offset (in bytes, regardless of architecture) into the executable.
0x804a378 is the actual address in which the error occurred.
With that said, it is important to understand what you can do about it.
First of all, compiling with -g will produce debug symbols. You, rightfully, strip those for your production build, but all is not lost. If you take your original executable (i.e. - before you striped it), you can run:
addr2line -e executable
You can then feed into stdin the addresses gdb is giving you (0x804a378), and addr2line will give you the precise file and line to which this address refers.
If you have a core file, you can also load this core file with the unstriped executable, and get full debug info. It would still be somewhat mangled, as you're probably building with optimizations, but some variables should, still, be accessible.
Building with debug symbols and stripping before shipping is the best option. Even if you did not, however, if you build the same sources again with the same build tools on the same environment and using the same build options, you should get the same binary with the same symbols locations. If the bug is really difficult to reproduce, it might be worthwhile to try.
EDITED to add
Two more important tools are c++filt. You feed it a mangled symbol, and produces the C++ path to the actual source symbol. It works as a filter, so you can just copy the backtrace and paste it into c++filt, and it will give you the same backtrace, only more readable.
The second tool is gdb remote debugging. This allows you to run gdb on a machine that has the executable with debug symbols, but run the actual code on the production machine. This allows live debugging in production (including attaching to already running processes).
You are confused. What you are seeing is backtrace output from glibc's backtrace function, not gdb's backtrace.
but I can't see the specific line in which the crash occurred because
the source code was not in that moment
Now you can load executable in gdb and examine the address 0x804a378 to get line numbers. You can use list *0x804a378 or info symbol 0x804a378. See Convert a libc backtrace to a source line number and How to use addr2line command in linux.
Run man gcc, there you should see -g option that gives you possibility to add debug information to the binary object file, so when crash happens and the core is dumped gdb can detect exact lines where and why the crash happened, or you can run the process using gdb or attach to it and see the trace directly without searching for the core file.

gdb/solaris: When attaching to a process, symbols not being loaded

I'm using gcc 4.9.2 & gdb 7.2 in Solaris 10 on sparc. The following was tested after compiling/linking with -g, -ggdb, and -ggdb3.
When I attach to a process:
~ gdb
/snip/
(gdb) attach pid_goes_here
... it is not loading symbolic information. I started with netbeans which starts gdb without specifying the executable name until after the attach occurs, but I've eliminated netbeans as the cause.
I can force it to load the symbol table under netbeans if I do one of the following:
Attach to the process, then in the debugger console do one of the following:
(gdb) detach
(gdb) file /path/to/file
(gdb) attach the_pid_goes_here
or
(gdb) file /path/to/file
(gdb) sharedlibrary .
I want to know if there's a more automatic way I can force this behavior. So far googling has turned up zilch.
I want to know if there's a more automatic way I can force this behavior.
It looks like a bug.
Are you sure that the main executable symbols are loaded? This bug says that attach pid without giving the binary doesn't work on Solaris at all.
In any case, it's supposed to work automatically, so your best bet to make it work better is probably to file a bug, and wait for it to be fixed (or send a patch to fix it yourself :-)

compile gdb source rpm with symbols using rpmbuild

I want to make gdb rpm from gdb.spec file using rpmbuld which I can do without any problem but now in addition to that i want GDB to be complied with symbols so that when gdb is being attached to itself I should know the exact call flow and where exactly its failing.
Reason for doing this exercise is I am creating the application which will internally invoke gdb by calling gdb_init and going down failing with segmentation fault in gdb source code.
The easiest way to prevent stripping debug symbols
in rpm build is to add exit 0 at the end of %install.
The symbols are stripped by commands that are appended
to the %install scriptlet. Adding "exit 0" prevents the
commands from being run.
I don't know how you would to this with rpmbuild, but building gdb is really easy. Just get official source package, unpack it, then configure this way:
CFLAGS="-g3 -O0" path/to/gdb/source/configure --prefix path/to/your/installation/directory
make
make install
O0 is not strictly necessary, but if you want to debug a gdb crash, it will help.

gdb: (no debugging symbols found)

I have a file called test. Even after compiling it with -g, when I run it in gdb, it says no debugging symbols found. I have also tried using -ggdb but it too was off no use. Please help.
Output for : gdb test
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /usr/bin/test...(no debugging symbols found)...done.
The issue is that you are attempting to debug the wrong program.
Your program is called test and yet you are debugging /usr/bin/test (a system program that will almost certainly be shipped without symbols; even if it did contain symbols, they wouldn't relate to your source code).
gdb will search $PATH to find the executable. From here:
exec-file [ filename ] Specify that the program to be run (but not the
symbol table) is found in filename. gdb searches the environment
variable PATH if necessary to locate your program. Omitting filename
means to discard information on the executable file.
Try using the command:
$ gdb ./test
Remove a.out and then try again. It worked for me as I was also getting the same error.
rm a.out
gcc -g your_code.c
Check that the executable is not stripped, you can see that with file /usr/bin/test