Debugging Rust and x64 assembly files together?

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?

Well, I narrowed down the problem to rustc's -g (or -C debuginfo=2) option. Without that option, I am able to debug correctly. With that option, LLDB doesn't know about file2.s. I've filed a bug report here.

1 Like