In GDB, I can use "info line func_name" to get the memory address of func_name, and then use "set $PC=memory_address" to start debugging this function. How do I do the same within lldb? Thanks in advance!
The command in lldb is "image lookup". I think an example of "info func" <-> "image lookup" was recently added to the lldb/gdb command page - http://lldb.llvm.org/lldb-gdb.html
e.g.
(lldb) im loo -n puts
1 match found in /usr/lib/system/libsystem_c.dylib:
Address: libsystem_c.dylib[0x0000000000011d9a] (libsystem_c.dylib.__TEXT.__text + 69850)
Summary: libsystem_c.dylib`puts
(lldb)
although this is only showing you the offset in libsystem_c.dylib here (0x11d9a) -- to see the actual load address you would need to use the "-v" option to image lookup which will show the range of addresses that puts covers. Or you could do this more directly with the back tick notation in lldb,
(lldb) reg read pc
rip = 0x0000000100000f2b a.out`main + 11 at a.c:3
(lldb) reg write pc `(void(*)())puts`
(lldb) reg read pc
rip = 0x00007fff99ce1d9a libsystem_c.dylib`puts
OK I had to cast puts() because lldb needed a function prototype here - not super convenient, but if it's one of your own functions that isn't needed:
(lldb) reg write pc `main`
(lldb) reg read pc
rip = 0x0000000100000f20 a.out`main at a.c:2
Related
I'm trying to step through this:
fn main() {
println!("Hello {}", 0);
}
I've tried compiling with both: cargo build and rustc -g -L src/main.rs
I then run gdb target/debug/rust-gdb-test (or gdb main), and try to set a breakpoint on main with break main.
(break ::rust-gdb-test::main returns Function "::rust-gdb-test" not defined.).
After breaking (Breakpoint 1, 0x0000555555559610 in main ()) if I try to run list, I get:
1 dl-debug.c: No such file or directory.
I am running Rust 1.10.0 (cfcb716cf 2016-07-03) and GDB 7.7.1 (Debian 7.7.1+dfsg-5).
A similar question was asked 2 years ago, but I couldn't make the solutions presented there to work.
Note: I seem to not have GDB installed anymore, only LLDB, but for this question the answer is the same.
The main that you see in Rust is not the same main that exists in the compiled binary. Specifically, there are a number of shim methods between the two. The Rust main actually includes the crate name (in my example buggin) and a hash (in my case hfe08615ed561bb88):
* frame #0: 0x000000010000126d buggin`buggin::main::hfe08615ed561bb88 + 29 at main.rs:2
frame #1: 0x000000010000810e buggin`std::panicking::try::call::hbbf4746cba890ca7 + 30
frame #2: 0x000000010000aadc buggin`__rust_try + 12
frame #3: 0x000000010000aa76 buggin`__rust_maybe_catch_panic + 38
frame #4: 0x0000000100007f32 buggin`std::rt::lang_start::hbcefdc316c2fbd45 + 562
frame #5: 0x00000001000013aa buggin`main + 42
frame #6: 0x00007fff910435ad libdyld.dylib`start + 1
frame #7: 0x00007fff910435ad libdyld.dylib`start + 1
Here, you can see that main is a few frames away in the stack.
I tend to use a wildcard breakpoint to not deal with the hash:
(lldb) br set -r 'buggin::main.*'
Breakpoint 5: where = buggin`buggin::main::hfe08615ed561bb88 + 29, address = 0x000000010000126d
rbreak should be an equivalent in GDB.
Once the program is stopped, you should be able to see the source. You may also be interested in the rust-lldb and rust-gdb wrappers that ship with Rust and improve the experience a bit.
This is basically the same as this answer, but mentions the hash.
Neither (gdb) rbreak 'rust-gdb-test::main.*' nor (lldb) br set -r 'rust-gdb-test::main.*' set any breakpoints for me.
The hyphen (-) is not a valid symbol character. When compiled, it is converted to an underscore.
My original methodology was actually this:
(lldb) br set -r '.*main.*'
Breakpoint 2: 67 locations.
You can then run the program and continue a few times until you find the right place. Don't be afraid to get in there and explore a bit; it's just a debugger!
You could try various versions of the regex to see if anything interesting might match:
(lldb) br set -r '.*main::.*'
Breakpoint 3: where = rust-gdb-test`rust_gdb_test::main::h97d2ac6fea75a245 + 29,
(lldb) br set -r '.*::main.*'
Breakpoint 4: where = rust-gdb-test`rust_gdb_test::main::h97d2ac6fea75a245 + 29,
You could also call a function with a very unique name from main and set a breakpoint on that:
(lldb) br set -r '.*a_really_unique_name.*'
I am writing a GDB macro to analyze the core and print a string. The output of string from core is "sp-4/0/2". Now I need to print only "sp", excluding others. I am not sure how to achieve this in GDB. Any pointers of this would be a great help.
Thanks in advance.
See, argv[1] is "sp-4/0/2"
(gdb) p argv[1]
$4 = 0x7fffffffe3fa "sp-4/0/2"
And this is only two first chars:
(gdb) printf "%.2s\n", argv[1]
sp
Or
(gdb) printf "%c%c\n", argv[1][0],argv[1][1]
sp
The following alternative works even when the size isn't known statically:
(gdb) p {char} argv[1]#2
I.e. you can replace the 2 by a variable or register value. This is useful when you are adding a breakpoint in e.g. write and don't have debug symbols available:
(gdb) b -qualified write # only match write, don't do globbing
(gdb) cond 1 $rdi == 2 # only when writing to stderr
(gdb) command 1
bt
p {char} $rsi#$rdx # print (partial) buffer
cont
The above works when the System V AMD64 calling convention is used, but can be easily adopted to the arm calling conventions by adapting the registers.
Let's say I'm debugging with valgrind and gdb by doing:
$ valgrind --vgdb-error=0 ./magic
...and then in a second terminal:
$ gdb ./magic
...
(gdb) target remote | /usr/lib/valgrind/../../bin/vgdb
If I want to examine the defined-ness of some memory, I can use:
(gdb) p &batman
$1 = (float *) 0xffeffe20c
(gdb) p sizeof(batman)
$2 = 4
(gdb) monitor get_vbits 0xffeffe20c 4
ffffffff
Using three commands to do one thing is kind of annoying, especially since I usually want to do this a few times for many different variables in the same stack frame. But if I try the obvious thing, I get:
(gdb) monitor get_vbits &batman sizeof(batman)
missing or malformed address
Is it possible to get gdb to evaluate &batman and sizeof(batman) on the same line as my monitor command?
But if I try the obvious thing, I get: missing or malformed address
This is from GDB doc (http://sourceware.org/gdb/onlinedocs/gdb/Connecting.html#index-monitor-1210) for the monitor cmd:
monitor cmd
This command allows you to send arbitrary commands
directly to the remote monitor. Since gdb doesn't care about the
commands it sends like this, this command is the way to extend gdb—you
can add new commands that only the external monitor will understand
and implement.
As you can see "gdb doesn't care about the commands it sends like this". It probably means that the command after monitor is not processed in any way and sent AS IS.
What you can do to evaluate your variable on the same line is to use user defined commands in gdb (http://sourceware.org/gdb/onlinedocs/gdb/Define.html). Define your own comand and use the eval gdb command to prepare your command with necessary values (http://sourceware.org/gdb/current/onlinedocs/gdb/Output.html#index-eval-1744):
define monitor_var
eval "monitor get_vbits %p %d", &$arg0, sizeof($arg0)
end
And then use it like this:
(gdb) monitor_var batman
The problem I am trying to solve is that I want to dynamically compute the length of an instruction given its address (from within GDB) and set that length as the value of a variable. The challenge is that I don't want any extraneous output printed to the console (e.g. disassembled instructions, etc.).
My normal approach to this is to do x/2i ADDR, then subtract the two addresses. I would like to achieve the same thing automatically; however, I don't want anything printed to the console. If I could disable console output then I would be able to do this by doing x/2i ADDR, followed by $_ - ADDR.
I have not found a way to disable the output of a command in GDB. If you know such a way then please tell me! However, I have discovered interpreter-exec and GDB/MI. A quick test shows that doing x/2i works on GDB/MI, and the value of $_ computed by the MI interpreter is shared with the console interpreter. Unfortunately, this approach also spits out a lot of output.
Does anyone know a way to either calculate the length of an instruction without displaying anything, or how to disable the output of interpreter-exec, thus allowing me to achieve my goal? Thank you.
I'll give an arguably cleaner and more extensible solution that's not really shorter. It implements $instn_length() as a new GDB convenience function.
Save this to instn-length.py
import gdb
def instn_length(addr_expr):
t = gdb.execute('x/2i ' + addr_expr, to_string=True)
return long(gdb.parse_and_eval('$_')) - long(gdb.parse_and_eval(addr_expr))
class InstnLength(gdb.Function):
def __init__(self):
super(InstnLength, self).__init__('instn_length')
def invoke(self, addr):
return instn_length(str(long(addr)))
InstnLength()
Then run
$ gdb -q -x instn-length.py /bin/true
Reading symbols from /usr/bin/true...Reading symbols from /usr/lib/debug/usr/bin/true.debug...done.
done.
(gdb) start
Temporary breakpoint 1 at 0x4014c0: file true.c, line 59.
Starting program: /usr/bin/true
Temporary breakpoint 1, main (argc=1, argv=0x7fffffffde28) at true.c:59
59 if (argc == 2)
(gdb) p $instn_length($pc)
$1 = 3
(gdb) disassemble /r $pc, $pc + 4
Dump of assembler code from 0x4014c0 to 0x4014c4:
An alternative implementation of instn_length() is to use the gdb.Architecture.disassemble() method in GDB 7.6+:
def instn_length(addr_expr):
addr = long(gdb.parse_and_eval(addr_expr))
arch = gdb.selected_frame().architecture()
return arch.disassemble(addr)[0]['length']
I have found a suitable solution; however, shorter solutions would be preferred. This solution sets a logging file to /dev/null, sets to to be overridden if it exists, and then redirects the console output to the log file temporarily.
define get-in-length
set logging file /dev/null
set logging overwrite on
set logging redirect on
set logging on
x/2i $arg0
set logging off
set logging redirect off
set logging overwrite off
set $_in_length = ((unsigned long) $_) - ((unsigned long) $arg0)
end
This solution was heavily inspired by another question's answer: How to get my program name in GDB when writting a "define" script?.
I am trying to match the gdb disassemble output (disas [address]) against the source code. I know that such mapping can be done using (gdb) info line *address to find the matching line. However I do not quite understand the format of the output of disassemble. Specifically, what do the following numbers, +4722, and +4281, mean ?
0x00002ad61e45bd02 <+4722>: jmpq 0x2ad61e45bb49 <MsgManager::ForwardMsg(boost::shared_ptr<Channel>, boost::shared_ptr<Msg>, boost::shared_ptr<Context>)+4281>
I am using GNU gdb (GDB) 7.4.1.
Specifically, what do the following numbers, +4722, and +4281, mean
The instruction at address 0x00002ad61e45bd02, which is 4722 bytes from the start of current function (most likely MsgManager::ForwardMsg()) is a jump to address 0x2ad61e45bb49, which is 4281 bytes from the start of MsgManager::ForwardMsg().
You may also find (gdb) disas/m command handy.