gdb in backtrack
They seem to be using this .gdbinit file:
https://github.com/gdbinit/Gdbinit/blob/master/gdbinit
How to go to the previous line in GDB?
Yes! With the new version 7.0 gdb, you can do exactly that!
The command would be "reverse-step
", or "reverse-next
".
You can get gdb-7.0 from ftp.gnu.org:/pub/gnu/gdb
If you run into the error: Target child does not support this command.
then try adding target record
at the beginning of execution, after starting run
.
Edit: Since GDB 7.6 target record
is deprecated, use target record-full
instead.
How to highlight and color gdb output during interactive debugging?
.gdbinit
You can tweak your ~/.gdbinit
to have colors. You can use mammon's .gdbinit
which is available here:
https://github.com/gdbinit/gdbinit
You can tweak it as much as you want too. I found this thanks to this SO answer. Here's the kind of output that you can obtain:
A GitHub repository is also available: https://github.com/gdbinit/Gdbinit
On a side note, the same idea was also applied to lldb.
GDB Dashboard
Following the same concept, GDB Dashboard provides a modular visual interface for GDB in Python.
(void)walker
Another similar project uses GDB's Python support to provide more extensibility, so this is worth checking out: https://github.com/dholm/voidwalker
@dholm also provides his own .gdbinit inspired from the previous one.
pwndbg
Some projects provide a set of useful functions, including improved display. This is the case for PEDA or pwndbg. The latter gives the following description:
A PEDA replacement. In the spirit of our good friend
windbg
,pwndbg
is pronouncedpwnd-bag
.
- Speed
- Resiliency
- Clean code
It provides commands to support debugging and exploit development similar to the ones from PEDA, and better display (although this is not the main focus of the project). The software is still under development, and has not been properly released yet.
voltron
The project description states:
Voltron is an extensible debugger UI for hackers. It allows you to
attach utility views running in other terminals to your debugger (LLDB
or GDB), displaying helpful information such as disassembly, stack
contents, register values, etc, while still giving you the same
debugger CLI you're used to.
You can modify your .gdbinit
to automatically integrate it. However, the display itself is outside of GDB (e.g. in a tmux split).
GEF
GEF is another option, and it is described as:
It is aimed to be used mostly by exploiters and reverse-engineers, to
provide additional features to GDB using the Python API to assist
during the process of dynamic analysis and exploit development.
Missing gdb symbols in Backtrace?
In ordinary code, gdb relies on debug information (and to a lesser extent the "linker" symbols) to find the names of functions as it unwinds. Debugging information is described in various standards, DWARF being the current best one for Linux. Compilers emit the debugging information that is then read by gdb.
For just-in-time compilers like OpenJDK, there is no agreed-upon solution to emitting debugging information for debuggers to read. And so, as you've found, gdb generally has no idea what is going on.
In fact, as you can see from your trace, gdb can't even really unwind the entire stack. That's what this means:
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
Modern compilers and ABIs tend to require some extra debugging information to unwind as well -- and, again, there's no agreement on how this should work for JIT compilation. GDB has some heuristics it uses to try to unwind when this information isn't available, but as you can see, they sometimes fail.
So, that's the bad news.
The good news is that gdb provides some ways to write unwinders and debug info readers for JITs. And, someone is working on this for OpenJDK. I wasn't able to quickly find the source, but I did find this thread which explains it a little.
How do you iterate a function in gdb with various inputs until you get a successful return value
Here is one way to do it.
For illustration purpose, let's assume that the program is:
#include <stdio.h>
int hash(unsigned int x) {
return ((x << 20) % 191) | (x % 57);
}
int main()
{
int j = 1;
printf("%d: %d\n", j, hash(j));
return 0;
}
I compile it with gcc -O3 -fno-inline t.c
, and observe this disassembly in GDB:
gdb -q ./a.out
Reading symbols from ./a.out...
(gdb) start
Temporary breakpoint 1 at 0x1050
Starting program: /tmp/a.out
Temporary breakpoint 1, 0x0000555555555050 in main ()
(gdb) disas hash
Dump of assembler code for function hash:
0x0000555555555170 <+0>: mov %edi,%ecx
0x0000555555555172 <+2>: mov $0xab8f69e3,%edx
0x0000555555555177 <+7>: shl $0x14,%ecx
0x000055555555517a <+10>: mov %ecx,%eax
0x000055555555517c <+12>: mul %edx
0x000055555555517e <+14>: mov %edi,%eax
0x0000555555555180 <+16>: shr $0x7,%edx
0x0000555555555183 <+19>: imul $0xbf,%edx,%edx
0x0000555555555189 <+25>: sub %edx,%ecx
0x000055555555518b <+27>: mov $0x1f7047dd,%edx
0x0000555555555190 <+32>: mul %edx
0x0000555555555192 <+34>: mov %edi,%eax
0x0000555555555194 <+36>: sub %edx,%eax
0x0000555555555196 <+38>: shr %eax
0x0000555555555198 <+40>: add %eax,%edx
0x000055555555519a <+42>: mov %ecx,%eax
0x000055555555519c <+44>: shr $0x5,%edx
0x000055555555519f <+47>: imul $0x39,%edx,%edx
0x00005555555551a2 <+50>: sub %edx,%edi
0x00005555555551a4 <+52>: or %edi,%eax
0x00005555555551a6 <+54>: retq
End of assembler dump.
Let's also assume that the return value I am looking for is 125
.
The first step is to set a conditional breakpoint on the retq
instruction:
(gdb) b *0x00005555555551a6 if $rax == 125
Breakpoint 2 at 0x5555555551a6
Now let's call hash()
in a loop:
set $j = 1240
while $j < 1260
> call (int)hash($j++)
> end
$1 = 63
$2 = 47
$3 = 189
$4 = 174
$5 = 191
$6 = 190
$7 = 177
$8 = 114
$9 = 119
$10 = 118
Breakpoint 2, 0x00005555555551a6 in hash ()
The program being debugged stopped while in a function called from GDB.
Evaluation of the expression containing the function
(hash) will be abandoned.
When the function is done executing, GDB will silently stop.
(gdb) p $j
$11 = 1251
So, calling hash(1250)
produces the desired value.
QED.
save gdb display to a variable
Not possible as far as I know, which is kind of surprising considering all the Lisp background of the author :) You'd need either redirection (grep
, sed
, and awk
make wonders on large files, and there's always perl
), or your own instruction decoding based on $pc
, which I assume is not an option.
Then I don't really understand what you are trying to do. Figure out jump targets? Relocation correctness? What is that you don't know about the code until the runtime? More details can probably point into better direction.
Edit:
Just some links - haven't tried it yet - you might want to play with script-extension
setting and see if you can make Python command files work for you:
see Extending GDB and Python in GDB.
Linux: Most powerful Debuggers
Eclipse has a good integrated debugging environment. It is a graphical wrapper over GDB - so you get the power of GDB, with an interface more like Xcode or Visual Studio.
As "GDB" is the only "real debugger" - (and thinks like "DDD" are wrappers over it) - Eclipse this is probably the debugger and IDE you're looking for.
Related Topics
How to Have Tcpdump Write to File and Standard Output the Appropriate Data
How to Use "Py" Instead of "Python" at the Command Line in Linux
Colored Shell Script Output Library
How to Replace Just One Newline Between > and < in Unix
Excluding Directory When Creating a .Tar.Gz File
Issue While Validating Bash Script
Implementing an Update/Upgrade System for Embedded Linux Devices
How to Grep One String Occuring Multiple Times from Same File
Symbolic Link to a Hook in Git
How to Format My Grep Output to Show Line Numbers at the End of the Line, and Also the Hit Count
Linux Cmd to Search for a Class File Among Jars Irrespective of Jar Path
How to Redirect the Output of an Application in Background to /Dev/Null
How to Enable Scrolling in Tmux Panels with Mouse Wheel
How to Clear All History in Linux/Ubuntu Terminal or Bash Permanently
Git Merge Branch of Another Remote