ghidra: Debugger not working for embedded ARM Cortex-M3 target
Describe the bug
When setting up Ghidra’s new debugger to work with gdb-multiarch connected to a GDB server opened by Renode (used as an ARM emulator here), debugging does not work correctly in the sense that:
- connecting to the GDB server works
- Ghidra shows one active thread and in which address / function it is
- but the “Dynamic” view is empty, the firmware assembly listing does not follow the program counter
- in the GDB console, the error
Can't determine the current process's PID: you must name oneappears - in the “Debug console”, the error “Could not list regions” appears, among others
- setting breakpoints in the assembly listing or in the decompiler view are not triggered (not even visible in the GDB console with
info breakpoints)
To Reproduce Steps to reproduce the behavior:
- Use the repo at https://github.com/maxgerhardt/ghidra-test-fw to download or compile the test firmware and the instructions on how to start Renode (+ its GDB server). The firmware is a simple Arduino-sketch for a STM32F103C8 (“Bluepill”) that prints “Hello, world” twice a second via UART2.
- Create a new Ghidra project, import the ELF file, override the detected architecture as the “Cortex” one, little endian (not ARMv8! Cortex-M3 is a ARMv7-M)
- Open the firmware in Ghidra’s debugger
- Let it analyze the firmware
- Have
gdb-multiarchinstalled (sudo apt install gdb-multiarchon Ubuntu) - Start a new debug connection as “IN-VM GNU gdb local debugger”, set “GDB launch command” to
/usr/bin/gdb-multiarch - Go to the interpreter window to be able to type GDB commands
- Execute initialization and connect commands (renode is running in the background) as
set architecture arm
set endian little
set arm fallback-mode thumb
set arm force-mode thumb
set style enabled off
file /home/max/ghidra-test-fw/.pio/build/genericSTM32F103C8/firmware.elf
target remote :3333
(adapt path to firmware.elfas needed)
9. Observe state of debugger, empty “Dynamic view”
Expected behavior The dynamic view is not empty and shows stuff.
Screenshots

Attachments
Needed firmware.elf and other instructions are in linked repo.
Environment (please complete the following information):
- OS: Xubuntu 21.04
- Java Version: 11.0
- Ghidra Version: 10.0.2 (public stable release)
- Ghidra Origin: ghidra-sre.org distro
Additional context
Similiar problems are reported in https://github.com/NationalSecurityAgency/ghidra/issues/3169 and possibly https://github.com/NationalSecurityAgency/ghidra/issues/2859. The code that prints the “Could not list regions” was added in https://github.com/NationalSecurityAgency/ghidra/commit/270c0b65a20bad68591398961cb351c845a5179d.
The README page at https://github.com/bootleg/ret-sync#embedded-devices-and-missing-procpidmaps also talks about the PID error.
Someone at https://wrongbaud.github.io/posts/ghidra-debugger/ seems to have gotten the debugger to work with an ARM target but no screenshot is shown of what the dynamic view looks like.
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 20 (1 by maintainers)
Commits related to this issue
- Merge remote-tracking branch 'origin/GP-1221_Dan_ARMorTHUMB' into patch (Closes #3333) — committed to NationalSecurityAgency/ghidra by ryanmkurtz 3 years ago
Apologies, I realized after I sent the last that you had already provided the information we needed. Didn’t mean to make extra work for you. I think we’ve isolated the base problem and will try to get a fix out to you ASAP. If you look in ghidra.app.plugin.core.debug.platform, you’ll see that the GdbArmDebuggerMappingOpinion is woefully incomplete. OffersForEnv is returning the Linux LE ARM offer for any architecture that begins with “arm” - obviously not good in your case. There’s some chance that just adding a clause for “armv7” would solve the problem, but would like to actually test that. The language model for ARM:LE:Cortex apparently knows enough to start in Thumb mode, which is why the Static listing has good disassembly, but I think we need more complete logic to process the existence/non-existence of cpsr, the behavior for xpsr, et cetera.
Will let you know when we have something in place, although, of course, feel free to experiment in the meantime!
Talking with @nsadeveloper789 today, I think there are two ways to do this, but am having trouble figuring one out myself so will wait until I get more info from him before describing how to do that. The other way is to define “maintenance info sections ALLOBJ” (and maybe actually “info proc mappings”). We have a sample for the latter in the distribution - look for the file “define_info_proc_mappings”. It basically tells gdb what to produce for that command, so that, when the debugger executes it, you get a result. After starting up your target, just “source define_info_proc_mappings” (with the path) in the Interpreter window. You’ll want to do the same for the former, i.e. “source define_maintenance” or whatever you call your script. The format is basically:
Object file: /path_to/firmware.elf 0x2000000->0x2004000 at 0x2000000: RAM ALLOC READ_WRITE 0x8000000->08010000 at 0x8000000: flash ALLOC READ_ONLY
I think - I haven’t looked at this in a while - so you’re script will basically “echo” those values. Yell, if this doesn’t make sense. (Also, there’s a bit more discussion in the the GitHub “Debugger” Discussions channel.)