5

I've tried to set breakpoint on every function that makes any sense but program exit before reaching any of those. Is there a way to make program run in step-by-step mode from the start so I can see what's going on?

I'm trying to debug /usr/bin/id if it's important (we have custom plugin for it and it's misbehaved)

P.S. Start command doesn't work for me here(it should be a comment, but I don't have enough rep for it)

Mendor
  • 85
  • 2
  • 8
  • Does this answer your question? [Stopping at the first machine code instruction in GDB](https://stackoverflow.com/questions/10483544/stopping-at-the-first-machine-code-instruction-in-gdb) – Peter Cordes Jan 28 '22 at 06:04
  • 1
    (GDB 8.1 introduced `starti`, and the linked duplicate explains older tricks that were usable even for PIE executables.) – Peter Cordes Jan 28 '22 at 06:05

4 Answers4

6

Get the program entry point address and insert a breakpoint at that address.

One way to do this is to do info files which gives you for example "Entry point: 0x4045a4". Then do "break *0x4045a4". After run-ning program, it will immediately stop.

From here on you can use single stepping instructions (like step or stepi) to proceed.

You did not tell what system you are trying to debug. If code is in read-only memory you may need to use hardware breakpoints (hbreak) if they are supported by that system.

dbrank0
  • 9,026
  • 2
  • 37
  • 55
  • The `set break` command seems to do something else at least in GDB 7.7.1 - it expects a subcommand rather than an address. Perhaps, you meant `break *0x4045a4`? – JSmyth May 24 '15 at 10:54
  • Sure. break not set break. Fixing answer. – dbrank0 May 24 '15 at 17:54
  • 1
    On Fedora 27, this works for Xorg [which is exempted from building as PIE etc](https://bugzilla.redhat.com/show_bug.cgi?id=1543960), but it does not work for most binaries e.g. `gnome-shell`. "Cannot insert breakpoint 1. Cannot access memory at address 0x2540". `break _start` will often work though (for C code, and I guess if the dynamic linker doesn't crash first). – sourcejedi Mar 28 '18 at 11:59
6

Use starti. Unlike start this stops at the actual first instruction, not at main().

Timmmm
  • 88,195
  • 71
  • 364
  • 509
  • This is the most useful answer. It works unconditionally for all programs, and it doesn't need any prior knowledge of the entry point address. – pts May 06 '23 at 15:18
5

Use start command

The ‘start’ command does the equivalent of setting a temporary breakpoint at the beginning of the main procedure and then invoking the ‘run’ command.

e.g.

a program with debug info main, and usage like this: main arg1 arg2

gdb main
(gdb) start arg1 arg2
herodot
  • 2,347
  • 1
  • 18
  • 10
1

You can type record full right after running the program. This will record all instructions and make them possible for replaying/going back.

For main function, you'd need to type this before reaching the breakpoint so you can set an earlier one by break _start -> _start is a function always called before the standard main function. (apparently applies only to the gcc compiler or similar)

Then continue to main breakpoint and do reverse-stepi to go exactly one instruction back

For more info about recording look here: link

h4nek
  • 86
  • 2
  • 8