I wanted to start using gdbserver for remote debugging and so I tested-out its functionality on my local machine with a simple test program that generates a segfault shown below:
segfault.c -- compiles to elf named "test"
#define NULL ((void*)0)
int main()
{
int value = *((int*)NULL);
return value;
}
Now when I run:
#gdb test
(gdb)run
I get:
Starting program: /home/awaibel/digiworkspace/test/Debug/test
Program received signal SIGSEGV, Segmentation fault.
0x080483bf in main () at ../segfault.c:4
4 int value = *((int*)NULL);
however if I debug it with gdb server like so:
#gdbserver :65535 test
#gdb test
(gdb)target remote 127.0.0.1:65535
(gdb)continue
it gives me the debug info:
Program received signal SIGSEGV, Segmentation fault.
0x080483bf in ?? ()
it seems to give the same function address for the segfault, but the name and line number is omitted when debugging with the remote debugger. is it possible to have the remote debugger display this information, and if so, how?
I guess I should add that the program was compiled with GCC using the "-g" debug flag
Thanks to markys' comments I was able to figure out the problem. Since the gdb client is what parses the symbols and not the server, I had to make sure the client knew the full path to a copy of the executable. Since 'test' was not in the current directory for the command prompt that was used to run gdbtest it did not have a copy of the symbols to use. adding the the binary to PATH for the terminal running the client solved the problem. Thanks.
Summarizing:
server side:
gdbserver --multi :port "path-to-executable"
client side:
gdb "path-to-executable"
(gdb)> target remote "ip-of-the-remote-device:port"
Related
We're learning to use GDB in my Computer Architecture class. To do this we do most of our work by using SSH to connect to a raspberry pi. When running GDB on some code he gave us to debug though it ends with an error message on how it can't find raise.c
I've tried:
installing libc6, libc6-dbg (says they're already up-to-date)
apt-get source glibc (gives me: "You must put some 'source' URIs in your sources.list")
https://stackoverflow.com/a/48287761/12015458 (apt source returns same thing as the apt-get source above, the "find $PWD" command the user gave returns nothing)
I've tried looking for it manually where told it may be? (/lib/libc doesn't exist for me)
This is the code he gave us to try debugging on GDB:
#include <stdio.h>
main()
{
int x,y;
y=54389;
for (x=10; x>=0; x--)
y=y/x;
printf("%d\n",y);
}
However, whenever I run the code in GDB I get the following error:
Program received signal SIGFPE, Arithmetic exception.
__GI_raise (sig=8) at ../sysdeps/unix/sysv/linux/raise.c:50
50 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
I asked him about it and he didn't really have any ideas on how to fix it.
It does not really matter that the source for raise() is not found. It would only show you the line where the exception is finally raised, but not the place where the error is triggered.
Run the erroneous program again in GDB. And when the exception is raised, investigate the call stack and the stackframes with GBDs commands. This is the point in your task, so I won't give you more than this hint.
If you're clever you can see the error in the given source just by looking at it. ;-)
When GDB does not know any symbol, you need to compile with the option -g to get debugger support.
EDIT
Now on a Windows system this is my log (please excuse the colouring, I didn't found a language selector for pure text):
D:\tmp\StackOverflow\so_027 > type crash1.c
#include <stdio.h>
main()
{
int x,y;
y=54389;
for (x=10; x>=0; x--)
y=y/x;
printf("%d\n",y);
}
D:\tmp\StackOverflow\so_027 > gcc crash1.c -g -o crash1.out
crash1.c:2:1: warning: return type defaults to 'int' [-Wimplicit-int]
main()
^~~~
D:\tmp\StackOverflow\so_027 > dir
[...cut...]
04.09.2019 08:33 144 crash1.c
04.09.2019 08:40 54.716 crash1.out
D:\tmp\StackOverflow\so_027 > gdb crash1.out
GNU gdb (GDB) 8.1
[...cut...]
This GDB was configured as "x86_64-w64-mingw32".
[...cut...]
Reading symbols from crash1.out...done.
(gdb) run
Starting program: D:\tmp\StackOverflow\so_027\crash1.out
[New Thread 4520.0x28b8]
[New Thread 4520.0x33f0]
Thread 1 received signal SIGFPE, Arithmetic exception.
0x0000000000401571 in main () at crash1.c:7
7 y=y/x;
(gdb) backtrace
#0 0x0000000000401571 in main () at crash1.c:7
(gdb) help stack
Examining the stack.
The stack is made up of stack frames. Gdb assigns numbers to stack frames
counting from zero for the innermost (currently executing) frame.
At any time gdb identifies one frame as the "selected" frame.
Variable lookups are done with respect to the selected frame.
When the program being debugged stops, gdb selects the innermost frame.
The commands below can be used to select other frames by number or address.
List of commands:
backtrace -- Print backtrace of all stack frames
bt -- Print backtrace of all stack frames
down -- Select and print stack frame called by this one
frame -- Select and print a stack frame
return -- Make selected stack frame return to its caller
select-frame -- Select a stack frame without printing anything
up -- Select and print stack frame that called this one
Type "help" followed by command name for full documentation.
Type "apropos word" to search for commands related to "word".
Command name abbreviations are allowed if unambiguous.
(gdb) next
Thread 1 received signal SIGFPE, Arithmetic exception.
0x0000000000401571 in main () at crash1.c:7
7 y=y/x;
(gdb) next
[Inferior 1 (process 4520) exited with code 030000000224]
(gdb) next
The program is not being run.
(gdb) quit
D:\tmp\StackOverflow\so_027 >
Well, it marks directly the erroneous source line. That is different to your environment as you use a Raspi. However, it shows you some GDB commands to try.
Concerning your video:
It is clear that inside raise() you can't access x. That's why GDB moans about it.
If an exception is raised usually the program is about to quit. So there is no value in stepping forward.
Instead, as shown in my log, use GDB commands to investigate the stack frames. I think this is the issue you are about to learn.
BTW, do you know that you should be able to copy the screen content? This will make reading so much easier for us.
From a practical standpoint the other answer is correct, but if you do want the libc sources:
apt-get source is the right way to get the sources of libc, but yes, you do need to have source repositories configured in /etc/apt/sources.list.
If you're using Ubuntu, see the deb-src lines in https://help.ubuntu.com/community/Repositories/CommandLine
For debian, see https://wiki.debian.org/SourcesList#Example_sources.list
Then apt-get source should work. Remember to tell GDB where those sources are using the "directory" command.
I'm trying to attach gdb to a program started by socat like this:
socat TCP-LISTEN:5678,reuseaddr,fork EXEC:./test
In another terminal,
sudo gdb
attach `pidof socat`
br *0x080487D4
when execute continue command in gdb, it shows error like this:
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x80487d4
Command aborted.
0x080487D4 is in .text of test program. The follow-fork-mode of gdb is child, I have searched online but still can't solve it.
I debugged program successfully like this way a month ago, and don't know why it doesn't work now. But it's ok if debug the program directly using gdb like this:
gdb -q ./test
However, the way above doesn't meet my needs.
Through debugging, I think gdb expects that address is a valid address in the socat rather then test program. So how can I set breakpoints in test program? Without breakpoints in test program, it will run directly to the end when execute continue command. Setting breakpoints in socat program is useless.
Any advice? Thanks in advance.
I have figured out how to set breakpoints in test program.
When start test program using socat, it won't fork a test process until a socket connection comes. So trying to set breakpoints directly in test program fails.
I use a tool(for my purpose, choose pwntools) to connect to it and suspend it ,then use gdb to attach to the forked test process. Next, I can debug normally.
Any better ideas? Thanks in advance.
core.1678,core.1689, how can i resolve this problem using gdb.i have tried gdb bt option but it is not resolving the error.
gdb -bt core.1678
(gdb) core
No core file now.
(gdb) n
The program is not being run.
(gdb) r
Starting program:
No executable file specified.
Use the "file" or "exec-file" command.
(gdb) core.1678
/home/deepak/deepak/mss/.1678: No such file or directory.
(gdb) /home/deepak/deepak/mss/core.1678
help me out
many core files( e.g core.1678 etc )...
This indicates that your same program or different programs in that particular directory is continuously crashing. When your machine is configured to generate dump file, it creates the file in the form of core.(PID). You may refer many useful article regarding the core dump file. You may refer my blog as well which explains about core dump analysis and its internal.
http://mantoshopensource.blogspot.sg/2011/02/core-dump-analysis-part-ii.html
The basic command to load and analyze the core dump file using GDB is as follows:
mantosh#ubuntu:~$ gdb
// This is how you would open the core dump file.
(gdb) core core.23515
(no debugging symbols found)
Core was generated by `./otest LinuxWorldRocks 10'.
Program terminated with signal 11, Segmentation fault.
[New process 23515]
==> Signal 11(SIGSEGV) was the reason for this core-dump file
==> pid of a program is 23515
#0 0x080485f8 in ?? ()
// Load the debug symbol of your program(build with -g option)
(gdb) symbol ./otest
Reading symbols from /home/mantosh/Desktop/otest...done.
// Now you can execute any normal command which you perform while debugging(except breakpoints).
(gdb) bt
#0 0x080485f8 in printf_info (info=0x8ec5008 "LinuxWorld") at test.c:58
#1 0x080485c2 in my_memcpy (dest=0x8ec5012 "", source=0xbfb9c6fe "Rocks",
length=10) at test.c:47
#2 0x0804855d in main (argc=3, argv=0xbfb9b3f4) at test.c:33
EDIT
cored-ump file is the snapshot of that particular program at the time of exception/segmentation fault. So once you load core-dump in GDB you would only be able to execute the command to read
the memory information. You can not use the debugging commands like breakpoints, continue, run ...etc..........
i'm trying to debug a C program, which runs on an ARM926EJ-S rev 5 (v5l). The software was cross-compiled (and is statically linked) with the std. arm-linux-gnueabi compiler (intalled via synaptic). I run Ubuntu 13.04 64bit. On the device is a Busybox v1.18.2. I successfully compiled gdbserver (with host=arm-linux-gnueabi) and gdb (with target=arm-linux-gnueabi) and can start my program on the embedded device via the locally running gdb...
My problem now is, that i don't have a proper backtrace output.
Message of gdb:
Remote debugging using 192.168.21.127:2345
0x0000a79c in ?? ()
(gdb) run
The "remote" target does not support "run". Try "help target" or "continue".
(gdb) continue
Continuing.
Cannot access memory at address 0x0
Program received signal SIGINT, Interrupt.
0x00026628 in ?? ()
(gdb) backtrace
#0 0x00026628 in ?? ()
#1 0x00036204 in ?? ()
#2 0x00036204 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb)
I try to compile the software with -g, -g3 -gdwarf-2, -ggdb, -ggdb3 without any difference.
Has anybody an idea what i am missing here?
Is this a problem maybe with the BusyBox or do i need additional libs on my host system?
I also tried the function backtrace_symbols from execinfo.h with nearly the same output...
Thanks in advance for any reply.
Another way for debugging is use gdb inside board follow below steps.
1)Run gdb process and attach your process to gdb using attach <pid> command
2)Continue your process using c command in gdb
Whenever you find any SIGINT or SIGSEGV then refer stack of your process using bt command in gdb.
I am trying to learn how to do buffer overflows by following this tutorial: http://www.ouah.org/readmeneu.htm but I can't get the exploit working.
Sources, exploit.c: http://pastebin.com/b95G2KK7 and server.c: http://pastebin.com/PM4GdcT7 . The shellcode that is being used is http://pastebin.com/fuGgDeAH .
I modified the exploit.c and the server.c to get them running.
Compiled server.c with -fno-stack-protector and set /proc/sys/kernel/randomize_va_space to 0. Also I tested the shellcode (gcc shellcode.c -z execstack; ./a.out; netcat 127.0.0.1 64713) and it works.
From what I understand the exploit.c does the following:
Fill buffer with NOP
Put shellcode in the middle of the buffer
Fill the end of the buffer with the wanted RET (0xbfff620)
Send the buffer (incl. shellcode)
The RET of the program then should execute the shellcode
So I load gdb and run the server program.
When executing the exploit program it gives a segmentation error and returns the right RET address.
Program received signal SIGSEGV, Segmentation fault.
0xbffff620 in ?? ()
The output of (gdb) 'x/400bx $esp-200' can be seen at the url: http://pastebin.com/bCqphFNn it looks correct..
Unfortunately the program does not open a port on 127.0.0.1 64713.
(gdb) show stack shows me:
eip = 0xbffff620; saved eip 0x90909090
called by frame at 0xbffff62c
Arglist at 0xbffff62c, args:
Locals at 0xbffff62c, Previous frame's sp is 0xbffff628
Saved registers:
ebp at 0xbffff620, eip at 0xbffff624
I'm not sure how to continue now; how can I get the exploit working? What am I missing?
* Updated *
I've compiled the server.c using the (-g) and the (-z execstack) options. When working from gdb: the exploit does seem to work (it opens a port on 64713). But when I try to connect to that port using nc or telnet the server.c receives a SIGSEGV signal (on 0xbffff6fc); the port 64713 is still open but does not respond to any commands..
Without gdb: the server.c still receives a segmentation fault when ./exploit is executed.. no port is opened.