Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is LLDB compatible with gdbserver (for debugging cross compiled code?)

Tags:

lldb

mips

I'm a CS student that just learned basic mips for class (Patterson & Hennessy + spim), and I'm attempting to find a mips debugging solution that allows arbitrary instruction execution during the debugging process.

Attempt with gdb (so you know why not to suggest this)

The recommended mips cross compilation tool chain is qemu and gdb, see mips.com docs and related Q/A.

gdb's compile code command does not support mips-linux-gnu-gcc as far as I can tell, see gdb docs ("Relocating the object file") and related Q/A. I get errors for malloc, mmap, and invalid memory errors (something appears to be going wrong with the ad-hoc linking gdb performs) when attempting to use compile code with mips-linux-gnu-gcc, even after filtering the hard coded compilation arguments that mips-linux-gnu-gcc doesn't recognize.

Actual question

lldb has a similar command called expression, see lldb docs, and I'm interested in using lldb in conjunction with qemu. The expression command also relies on clang as opposed to gcc, but cross compilation in clang is relatively simple (clang -target mips-linux-gnu "just works"). The only issue is that qemu-mips -g launches gdbserver, and I can find no option for launching lldb-server.

I have read lldb docs on remote debugging, and there is an option to select remote-gdb-server as the platform. I can't find much in the way of documentation for remote-gdb-server, but the name seems to imply that lldb can be compatible with gdbserver.

Here is my attempt to make this work:

qemu-mips -g 1234 test

lldb test
(lldb) platform select remote-gdb-server
  Platform: remote-gdb-server
  Connected: no
(lldb) platform connect connect://localhost:1234
  Platform: remote-gdb-server
  Hostname: (null)
  Connected: yes
(lldb) b main
  Breakpoint 1: where = test`main + 16 at test.c:4, address = 0x00400530
(lldb) c
  error: invalid process

Is there a way to either

  1. use lldb with gdbserver, or to
  2. launch lldb-server from qemu-mips as opposed to gdbserver

so that I can execute instructions while debugging mips code?

Note: I understand that I could instead use qemu system emulation to be able to just run lldb-server on the remote. I have tried to virtualize debian mips, using this guide, but the netinstaller won't detect my network card. Based on numerous SO Q/A and online forums, it looks like solving this problem is hard. So for now I am trying to avoid whole system emulation.

like image 984
okovko Avatar asked Mar 30 '20 09:03

okovko


People also ask

Can you use LLDB with GCC?

Supported compilers for building LLDB on Linux include: Clang 3.2. GCC 4.6. 2 (later versions should work as well)

Is LLDB better than GDB?

Both GDB and LLDB are of course excellent debuggers without doubt. GDB is debugger part of the GNU project created to work along the GNU compiler. LLDB is debugger part of the LLVM project created to work along LLVM compiler. The majority of the commands are the same.

How do I start gdbserver on target?

To start "gdbserver" without supplying an initial command to run or process ID to attach, use the --multi command line option. In such case you should connect using "target extended-remote" to start the program you want to debug.


1 Answers

YES

Use LLDB with QEMU

LLDB supports GDB server that QEMU uses, so you can do the same thing with the previous section, but with some command modification as LLDB has some commands that are different than GDB You can run QEMU to listen for a "GDB connection" before it starts executing any code to debug it.

qemu -s -S <harddrive.img>

...will setup QEMU to listen on port 1234 and wait for a GDB connection to it. Then, from a remote or local shell:


lldb kernel.elf
(lldb) target create "kernel.elf"
Current executable set to '/home/user/osdev/kernel.elf' (x86_64).
(lldb) gdb-remote localhost:1234
Process 1 stopped
* thread #1, stop reason = signal SIGTRAP
    frame #0: 0x000000000000fff0
->  0xfff0: addb   %al, (%rax)
    0xfff2: addb   %al, (%rax)
    0xfff4: addb   %al, (%rax)
    0xfff6: addb   %al, (%rax)

(Replace localhost with remote IP / URL if necessary.) Then start execution:

(lldb) c
Process 1 resuming

To set a breakpoint:

(lldb) breakpoint set --name kmain
Breakpoint 1: where = kernel.elf`kmain, address = 0xffffffff802025d0

for your situation:

  1. qemu-mips -s -S test;
  2. lldb test
  3. gdb-remote localhost:1234

here is my,you can reference:


#############################################   gdb    #############################################
QEMU_GDB_OPT := -S -gdb tcp::10001,ipv4
# 调试配置:-S -gdb tcp::10001,ipv4
qemudbg:
ifeq ($(BOOT_MODE),$(BOOT_LEGACY_MODE))
    $(QEMU) $(QEMU_GDB_OPT) $(QEMU_ARGUMENT)
else
ifeq ($(BOOT_MODE),$(BOOT_GRUB2_MODE))
ifeq ($(EFI_BOOT_MODE),n)
    $(QEMU) $(QEMU_GDB_OPT) $(QEMU_ARGUMENT) -cdrom $(KERNSRC)/$(OS_NAME).iso
else
    $(QEMU) $(QEMU_GDB_OPT) $(QEMU_ARGUMENT) -bios $(BIOS_FW_DIR)/IA32_OVMF.fd -cdrom $(KERNSRC)/$(OS_NAME).iso
endif
endif
endif

# 连接gdb server: target remote localhost:10001
gdb:
    $(GDB) $(KERNEL_ELF)


#############################################   lldb    #############################################

QEMU_LLDB_OPT := -s -S
LLDB := lldb

qemulldb:
ifeq ($(BOOT_MODE),$(BOOT_LEGACY_MODE))
    $(QEMU) $(QEMU_LLDB_OPT) $(QEMU_ARGUMENT)
else
ifeq ($(BOOT_MODE),$(BOOT_GRUB2_MODE))
ifeq ($(EFI_BOOT_MODE),n)
    $(QEMU) $(QEMU_LLDB_OPT) $(QEMU_ARGUMENT) -cdrom $(KERNSRC)/$(OS_NAME).iso
else
    $(QEMU) $(QEMU_LLDB_OPT) $(QEMU_ARGUMENT) -bios $(BIOS_FW_DIR)/IA32_OVMF.fd -cdrom $(KERNSRC)/$(OS_NAME).iso
endif
endif
endif


lldb:
    $(LLDB) $(KERNEL_ELF)


like image 95
Princekin Avatar answered Oct 26 '22 23:10

Princekin