3

I'm trying to find a segmentation fault in my program that doesn't happen all the time. I'm trying to run my program in a loop in gdb until the segmentation fault happens.

My problem is that the gdb continues the while loop after receiving the seg fault and doesn't prompt me with the gdb shell.

when I run my gdb I use:

set $i=0
while($i<100)
  set $i = $i+1
  r
end

Anybody know how to make the gdb stop at first segfault and not run 100 times??

Thanks!

dlmeetei
  • 9,905
  • 3
  • 31
  • 38
Netap
  • 193
  • 1
  • 10

2 Answers2

1

The gdb documentation is huge and it's difficult to find what you want but I could make that happen, and just by tweaking your script slightly.

Upon completion, gdb sets $_exitcode to the exit code value.

If segv occurs, the value isn't changed. So my idea was to set it to some stupid value (I chose 244) and run. But if return code is still 244 after the run command, then exit the loop (maybe there's another way to do it)

Warning: hack ahead (but that works)

set $i=0
while($i<100)
  set $i = $i+1
  set $_exitcode = 244
  r
  if $_exitcode==244
    set $i = 200
  end
end

I tested that with an interactive program. Type n for normal execution, and y to trigger segfault (well it would not trigger it, but there's a good chance for that to happen)

#include <stdio.h>
#include <stdlib.h>

int main()
{
   printf("want segfault?\n");
   char c = getchar();
   if (c=='y')
   {
    printf("%s", 'a');  // this is broken on purpose, to trigger segfault
   }
   return 0;
}

testing in a gdb session:

(gdb) source gdbloop.txt
[New Thread 6216.0x1d2c]
want segfault?
n
[Inferior 1 (process 6216) exited normally]
[New Thread 7008.0x1264]
want segfault?
n
[Inferior 1 (process 7008) exited normally]
[New Thread 8000.0x2754]
want segfault?
y

Breakpoint 1, 0x76b2d193 in wtoi () from C:\windows\syswow64\msvcrt.dll
(gdb) 

so I get the prompt back when a segfault is triggered.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
0

You can script GDB interaction using expect.

But the solution from this answer should really be all you need here.

break on exit didn't work for me

It's possible that your program calls _exit instead of exit, so you may need to set a breakpoint there.

It's also possible that your program executes direct SYS_exit system call without going through either exit or _exit.

On Linux, you can catch this with:

catch syscall exit
catch syscall exit_group

At least one the four variants should fire (just run a program by hand). Once you know which variant actually fires, attach commands to the corresponding breakpoint, and use the solution above.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362