gdb crash when using breakpoints - crash

In every program I try to debug, I am getting the same result, every time I use breakpoints and try to run any program gdb crash. I tried the same thing on different programs and it keeps acting like this.
I will show the result on this simple:
int main(int argc,char* argv[]){
for(int i = 0;i < 200; i++){
printf("%d\n",i);
}
}
gcc main.c -m32 -std=c99 -o test
GNU gdb (Debian 8.3-1) 8.3
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from test...
(No debugging symbols found in test)
(gdb) disas main
Dump of assembler code for function main:
0x00001199 <+0>: lea 0x4(%esp),%ecx
0x0000119d <+4>: and $0xfffffff0,%esp
0x000011a0 <+7>: pushl -0x4(%ecx)
0x000011a3 <+10>: push %ebp
0x000011a4 <+11>: mov %esp,%ebp
0x000011a6 <+13>: push %ebx
0x000011a7 <+14>: push %ecx
0x000011a8 <+15>: sub $0x10,%esp
0x000011ab <+18>: call 0x10a0 <__x86.get_pc_thunk.bx>
0x000011b0 <+23>: add $0x2e50,%ebx
0x000011b6 <+29>: movl $0x0,-0xc(%ebp)
0x000011bd <+36>: jmp 0x11d8 <main+63>
0x000011bf <+38>: sub $0x8,%esp
0x000011c2 <+41>: pushl -0xc(%ebp)
0x000011c5 <+44>: lea -0x1ff8(%ebx),%eax
0x000011cb <+50>: push %eax
0x000011cc <+51>: call 0x1030 <printf#plt>
0x000011d1 <+56>: add $0x10,%esp
0x000011d4 <+59>: addl $0x1,-0xc(%ebp)
0x000011d8 <+63>: cmpl $0xc7,-0xc(%ebp)
0x000011df <+70>: jle 0x11bf <main+38>
0x000011e1 <+72>: mov $0x0,%eax
0x000011e6 <+77>: lea -0x8(%ebp),%esp
0x000011e9 <+80>: pop %ecx
0x000011ea <+81>: pop %ebx
0x000011eb <+82>: pop %ebp
0x000011ec <+83>: lea -0x4(%ecx),%esp
0x000011ef <+86>: ret
End of assembler dump.
(gdb) break *0x000011ef
Breakpoint 1 at 0x11ef
(gdb) run
Starting program: /root/test
[1]+ Stopped gdb test
I tried to do the same thing in another linux machine, and it works fine. So what could be the problem?
Update: I found a temp solution for the breakpoints issue (so gdb do not crash), You use the command (start) at the beginning and everything will work fine :
GNU gdb (Debian 8.3-1) 8.3
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from test...
(No debugging symbols found in test)
(gdb) start
Temporary breakpoint 1 at 0x11a8
Starting program: /root/test
Temporary breakpoint 1, 0x565561a8 in main ()
(gdb) enable
(gdb) disas main
Dump of assembler code for function main:
0x56556199 <+0>: lea 0x4(%esp),%ecx
0x5655619d <+4>: and $0xfffffff0,%esp
0x565561a0 <+7>: pushl -0x4(%ecx)
0x565561a3 <+10>: push %ebp
0x565561a4 <+11>: mov %esp,%ebp
0x565561a6 <+13>: push %ebx
0x565561a7 <+14>: push %ecx
=> 0x565561a8 <+15>: sub $0x10,%esp
0x565561ab <+18>: call 0x565560a0 <__x86.get_pc_thunk.bx>
0x565561b0 <+23>: add $0x2e50,%ebx
0x565561b6 <+29>: movl $0x0,-0xc(%ebp)
0x565561bd <+36>: jmp 0x565561d8 <main+63>
0x565561bf <+38>: sub $0x8,%esp
0x565561c2 <+41>: pushl -0xc(%ebp)
0x565561c5 <+44>: lea -0x1ff8(%ebx),%eax
0x565561cb <+50>: push %eax
0x565561cc <+51>: call 0x56556030 <printf#plt>
0x565561d1 <+56>: add $0x10,%esp
0x565561d4 <+59>: addl $0x1,-0xc(%ebp)
0x565561d8 <+63>: cmpl $0xc7,-0xc(%ebp)
0x565561df <+70>: jle 0x565561bf <main+38>
0x565561e1 <+72>: mov $0x0,%eax
0x565561e6 <+77>: lea -0x8(%ebp),%esp
0x565561e9 <+80>: pop %ecx
0x565561ea <+81>: pop %ebx
0x565561eb <+82>: pop %ebp
0x565561ec <+83>: lea -0x4(%ecx),%esp
0x565561ef <+86>: ret
End of assembler dump.
(gdb) break *0x565561df
Breakpoint 2 at 0x565561df
(gdb) info break
Num Type Disp Enb Address What
2 breakpoint keep y 0x565561df <main+70>
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/test
Breakpoint 2, 0x565561df in main ()
(gdb) step
Single stepping until exit from function main,
which has no line number information.
0
Breakpoint 2, 0x565561df in main ()
(gdb)
Single stepping until exit from function main,
which has no line number information.
1
Breakpoint 2, 0x565561df in main ()
(gdb)
Single stepping until exit from function main,
which has no line number information.
2
Breakpoint 2, 0x565561df in main ()
(gdb)
Single stepping until exit from function main,
which has no line number information.
3
Breakpoint 2, 0x565561df in main ()
(gdb)
Single stepping until exit from function main,
which has no line number information.
4
Breakpoint 2, 0x565561df in main ()
Unfortunately, This is a temp solution just so you can deal with breakpoints, and it have nothing to do with the crashing problem.

You are most likely trying to set a breakpoint at an invalid address with this command break *0x000011ef. The 0x11ef is the offset of that instruction within the section within the ELF, but the program is going to be relocated when it is loaded / started.
You should instead try start, then disas main, and then place your breakpoint.
GDB stopping like this is a bug which occurs when GDB throws an error while trying to place a breakpoint, it was fixed in upstream GDB with this patch:
https://sourceware.org/ml/gdb-patches/2019-05/msg00361.html
Once you see GDB stopped like this:
[1]+ Stopped gdb soQuestionProgram
you should be dropped back to a shell. Just resume GDB with the fg command and continue your debug session. Once GDB 8.4 is out this bug will be fixed.

it keeps acting like this
First: GDB did not crash. It merely got stopped (by your shell). You can get it back with the shell fg command.
Second: this has nothing to do with GDB, and something to do with your terminal configuration. Using reset may cure this problem.

Related

gdb can not `next` over an non system dll function call

The problem is with the debugging code that has a call to some dll function, this one and others from the same dll:
EdsGetCameraList(&l);
when I break on this line and then issue a next command, I get a
(gdb) n
0x1000e620 in ?? ()
0x1000e620 is address of EdsGetCameraList:
(gdb) disas find_cam,+20
Dump of assembler code from 0x401783 to 0x401797:
0x00401783 <find_cam+0>: push ebp
0x00401784 <find_cam+1>: mov ebp,esp
0x00401786 <find_cam+3>: sub esp,0x48
=> 0x00401789 <find_cam+6>: lea eax,[ebp-0x14]
0x0040178c <find_cam+9>: mov DWORD PTR [esp],eax
0x0040178f <find_cam+12>: mov eax,ds:0x4092dc
0x00401794 <find_cam+17>: call eax
0x00401796 <find_cam+19>: sub esp,0x4
End of assembler dump.
(gdb) x 0x4092dc
0x4092dc <_imp__EdsGetCameraList#4>: 0x1000e620
No wonder if I type next again I get:
(gdb) n
Cannot find bounds of current function
What is going on?
next steps over source lines - you need the debug information for the dll you're debugging if you want to do source line stepping. In this case there is no debug info available and gdb doesn't know where source lines start/end -- next won't do anything.
Instead you'll need to use the instruction-level step commands, nexti and stepi (ni, si) to single instruction step through these routines. You can also use finish to return to the caller function.
When people debug with gdb at this level, they often have gdb display the next few instructions as they step -- do disp/3i $pc to have the next three instructions displayed.

How to jump into bootloader in Ada?

I am writing embedded code in Ada. I want to jump into bootloader code which is located at address 0x0E00. I am trying to use following code:
with Interfaces; use Interfaces;
with System;
package AVR.bootloader is
procedure Call;
pragma No_Return(Call);
pragma Import (Assembler,Call);
for Call'Address use System'To_Address (16#0E00#);
end AVR.bootloader;
The problem is this does not work.
Edit: I want to do a following C equivalent:
void (*boot)(void)=0x0E00;
I did a small experiment on this Macbook Pro, and your code seems to do what you meant it to; I modified the code to read
with System;
procedure Bootloader is
procedure Call;
pragma No_Return (Call);
pragma Import (Assembler, Call);
for Call'Address use System'To_Address (16#0E00#);
begin
Call;
end Bootloader;
and when I compile with gnatmake -c -u -f -S bootloader.adb the saved assembler is
.text
.globl __ada_bootloader
__ada_bootloader:
LFB1:
pushq %rbp
LCFI0:
movq %rsp, %rbp
LCFI1:
subq $16, %rsp
LCFI2:
movq $3584, -8(%rbp)
movq -8(%rbp), %rax
call *%rax
leave
LCFI3:
ret
[...]
which looks hopeful, though I’m not familiar enough with asm to know.
Running it under gdb I get (after a lot of chatter)
(gdb) run
Starting program: /Users/simon/tmp/bootloader
Reading symbols for shared libraries ++........................ done
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000e00
0x0000000000000e00 in ?? ()
(gdb) bt
#0 0x0000000000000e00 in ?? ()
Cannot access memory at address 0xe00
#1 0x0000000100000d93 in main (argc=1, argv=140734799805048, envp=140734799805064) at /Users/simon/tmp/b~bootloader.adb:121
#2 0x0000000100000bf4 in start ()
which looks even more hopeful.
Perhaps your AVR compiler isn’t code-generating properly?
Since normally a boot-loader runs on reset, the simplest method is to force a processor reset. A boot-loader may reasonably assume that it is running on an uninitialised system in reset state and may perform initialisation that is not valid on an already initialised system, so forcing a reset is the safest method.
Your processor may have a reset instruction or a reset controller that can perform this directly. Failing that it may have a watchdog timer that can generate a reset. Start the watchdog timer with a suitably short time-out and let it run without servicing it.

How to print disassembly registers in the Xcode console

I'm looking at some disassembly code and see something like 0x01c8f09b <+0015> mov 0x8(%edx),%edi and I am wondering what the value of %edx or %edi is.
Is there a way to print the value of %edx or other assembly variables? Is there a way to print the value at the memory address that %edx points at (I'm assuming edx is a register containing a pointer to ... something here).
For example, you can print an objet by typing po in the console, so is there a command or syntax for printing registers/variables in the assembly?
Background:
I'm getting EXC_BAD_ACCESS on this line and I would like to debug what is going on. I'm aware this error is related to memory management and I'm looking at figuring out where I may be missing/too-many retain/release/autorelease calls.
Additional Info:
This is on IOS, and my application is running in the iPhone simulator.
You can print a register (e.g, eax) using:
print $eax
Or for short:
p $eax
To print it as hexadecimal:
p/x $eax
To display the value pointed to by a register:
x $eax
Check the gdb help for more details:
help print
help x
Depends up which Xcode compiler/debugger you are using. For gcc/gdb it's
info registers
but for clang/lldb it's
register read
(gdb) info reg
eax 0xe 14
ecx 0x2844e0 2639072
edx 0x285360 2642784
ebx 0x283ff4 2637812
esp 0xbffff350 0xbffff350
ebp 0xbffff368 0xbffff368
esi 0x0 0
edi 0x0 0
eip 0x80483f9 0x80483f9 <main+21>
eflags 0x246 [ PF ZF IF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
From Debugging with gdb:
You can refer to machine register contents, in expressions, as variables with names
starting with `$'. The names of registers are different for each machine; use info
registers to see the names used on your machine.
info registers
Print the names and values of all registers except floating-point
registers (in the selected stack frame).
info all-registers
Print the names and values of all registers, including floating-point
registers.
info registers regname ...
Print the relativized value of each specified register regname.
regname may be any register name valid on the machine you are using,
with or without the initial `$'.
If you are using LLDB instead of GDB you can use register read
Those are not variables, but registers.
In GDB, you can see the values of standard registers by using the following command:
info registers
Note that a register contains integer values (32bits in your case, as the register name is prefixed by e). What it represent is not known. It can be a pointer, an integer, mostly anything.
If po crashes when you try to print a register's value as a pointer, it's likely that the value is not a pointer (or an invalid one).

GDB backtrace don't show function names on Mac

I was testing some things with gdb with this code (it's a wrong code, i use it just for testing purposes):
#import <Foundation/Foundation.h>
int main (int argc, char **argv)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int i = 1;
NSLog(#"Hi GDB, i is %#", i);
[pool release];
return 0;
}
Then i compile it : gcc -Wall -g -framework Foundation testGdb.m -o testGdb, and i run it:
gdb ./a.out
GNU gdb 6.3.50-20050815 (Apple version gdb-1518) (Sat Feb 12 02:52:12 UTC 2011)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin"...Reading symbols for shared libraries ..... done
(gdb) run
Starting program: /Users/Tarek/Desktop/a.out
Reading symbols for shared libraries .++++....................... done
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x000000000000002a
0x00007fff82d7a0a3 in objc_msgSend_fixup ()
(gdb) bt
#0 0x00007fff82d7a0a3 in objc_msgSend_fixup ()
#1 0x0000000000000000 in ?? ()
(gdb)
The strange thing is that ther's no name in (#1), the correct output would normally print NSLog(the cause of the crash) and main.
Thanks for helping to understand this strange behavior.
This answer is most likely applicable here as well.
Debug symbols have nothing to do with the problem -- GDB can unwind stack just fine without them (only unwind descriptors are necessary).

Is the gcc insane optimisation level (-O3) not insane enough?

As part of answering another question, I wanted to show that the insane level of optimisation of gcc (-O3) would basically strip out any variables that weren't used in main. The code was:
#include <stdio.h>
int main (void) {
char bing[71];
int x = 7;
bing[0] = 11;
return 0;
}
and the gcc -O3 output was:
.file "qq.c"
.text
.p2align 4,,15
.globl main
.type main, #function
main:
pushl %ebp
xorl %eax, %eax
movl %esp, %ebp
popl %ebp
ret
.size main, .-main
.ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
.section .note.GNU-stack,"",#progbits
Now I can see it's removed the local variables but there's still quite a bit of wastage in there. It seems to me that the entire:
pushl %ebp
xorl %eax, %eax
movl %esp, %ebp
popl %ebp
ret
section could be replaced with the simpler:
xorl %eax, %eax
ret
Does anyone have any idea why gcc does not perform this optimisation? I know that would save very little for main itself but, if this were done with normal functions as well, the effect of unnecessarily adjusting the stack pointer in a massive loop would be considerable.
The command used to generate the assembly was:
gcc -O3 -std=c99 -S qq.c
You can enable that particular optimization with the -fomit-frame-pointer compiler flag. Doing so makes debugging impossible on some machines and substantially more difficult on everything else, which is why it's usually disabled.
Although your GCC documentation may say that -fomit-frame-pointer is enabled at various optimization levels, you'll likely find that that's not the case—you'll almost certainly have to explicitly enable it yourself.
Turning on -fomit-frame-pointer (source) should get rid of the extra stack manipulations.
GCC apparently left those in because they facilitate debugging (getting a stack trace when needed), although the docs note that -fomit-frame-pointer is the default starting with GCC 4.6.