I've got what I hope is not too obscure an issue to find an answer. I've got a project with both Rust code and x64 assembly and I'd like to be able to debug it, stepping through both. Unfortunately when I put everything through the Rust tools, it seems all references to my assembly files are somehow removed from the resulting binary.
Here is a simple repository set up how I think this should work. I think it should compile and assemble on a Mac, Linux, and maybe Windows with mingw or something, but I've only tried on a Mac. It does need nightly because I use the "sysv64" ABI, and I'm also using clang as my assembler.
Now I do this:
$ cargo build
Compiling debug_mixed v0.1.0 (file:///Users/mike/Dropbox/Repositories/debug_mixed)
Finished dev [unoptimized + debuginfo] target(s) in 0.97 secs
$ lldb target/debug/debug_mixed
(lldb) target create "target/debug/debug_mixed"
Current executable set to 'target/debug/debug_mixed' (x86_64).
(lldb) breakpoint set --file file.c --line 4
Breakpoint 1: where = debug_mixed`c_function + 15 at file.c:4, address = 0x000000010000157f
(lldb) breakpoint set --file file2.s --line 9
Breakpoint 2: no locations (pending).
WARNING: Unable to resolve breakpoint to any actual locations.
(lldb) breakpoint set -name asm_function
Breakpoint 3: where = debug_mixed`asm_function, address = 0x000000010000158d
(lldb) run
Process 67367 launched: '/Users/mike/Dropbox/Repositories/debug_mixed/target/debug/debug_mixed' (x86_64)
Hello, world!
Process 67367 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x000000010000157f debug_mixed`c_function at file.c:4
1 #include <stdio.h>
2
3 void c_function(void) {
-> 4 puts("In the C function");
5 }
(lldb) continue
Process 67367 resuming
In the C function
Process 67367 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 3.1
frame #0: 0x000000010000158d debug_mixed`asm_function
debug_mixed`asm_function:
-> 0x10000158d <+0>: leaq 0x4fdfc(%rip), %rdi ; message
0x100001594 <+7>: subq $0x8, %rsp
0x100001598 <+11>: callq 0x100042f3e ; symbol stub for: puts
0x10000159d <+16>: addq $0x8, %rsp
What happened here is that I set a breakpoint in the C file, which works fine. I try to set a breakpoint in the assembly file, but LLDB doesn't know what file I'm talking about. Instead, I set a breakpoint by the name of the assembly function.
Then I run and hit the breakpoint in the C file. I continue and hit the breakpoint in the assembly file, but LLDB doesn't know about the file; instead, it's just displaying disassembly, not what I wrote.
So LLDB doesn't appear to be aware of file2.s
.
Now it's hard to imagine how this could have anything to do with Cargo or rustc
, but it must, because if I eliminate the Rust stuff, and just use C code with clang
and ar
to duplicate exactly what I think is happening with Cargo, it all works fine:
$ clang -g -c src/main.c -o target/main.o
$ clang -g -c src/file.c -o target/file.o
$ clang -g -c src/file2.s -o target/file2.o
$ ar crus target/libfile.a target/file.o target/file2.o
$ clang target/main.o target/libfile.a -o target/debug_mixed_c
$ lldb target/debug_mixed_c
(lldb) target create "target/debug_mixed_c"
Current executable set to 'target/debug_mixed_c' (x86_64).
(lldb) breakpoint set --file file.c --line 4
Breakpoint 1: where = debug_mixed_c`c_function + 15 at file.c:4, address = 0x0000000100000f4f
(lldb) breakpoint set --file file2.s --line 8
Breakpoint 2: where = debug_mixed_c`asm_function, address = 0x0000000100000f5d
(lldb) run
Process 67539 launched: '/Users/mike/Dropbox/Repositories/debug_mixed/target/debug_mixed_c' (x86_64)
Process 67539 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100000f4f debug_mixed_c`c_function at file.c:4
1 #include <stdio.h>
2
3 void c_function(void) {
-> 4 puts("In the C function");
5 }
(lldb) continue
Process 67539 resuming
In the C function
Process 67539 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
frame #0: 0x0000000100000f5d debug_mixed_c`asm_function at file2.s:8
5
6 asm_function:
7 _asm_function:
-> 8 lea rdi, [rip + message]
9 sub rsp, 8
10 call _puts
11 add rsp, 8
So... any thoughts on why using the Rust tools is somehow preventing LLDB from knowing about file2.s
? And what I can do to fix this situation?