qilingframework / qilingframework/qiling
GDB debugging STM32f1xx stops execution after interrupt
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 6.1k
- Forks
- 798
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 9
Description
[ disclaimer: to get below code to work I copied the gdb target XML files of 'arm' to 'qiling/debugger/gdb/xml/cortex_m' and put back the 'setup_remap' function in 'hw/hw.py' (STM32 uses aliased memory). The former might have something to do with this? ]
I'm using -dev of today (+/- 1hr ago) to do remote GDB debugging on an STM32f10x target. Attaching works, GDB stops at the entry point but then when I just let the firmware continue 'c', an interrupt 0x2 is caught and directly afterwards my script stops execution.
ql = Qiling(["firmware.hex"], archtype="cortex_m", env=stm32f105,verbose=QL_VERBOSE.DEBUG)
ql.hw.create('rcc')
ql.hw.create('flash interface')
ql.hw.create('exti')
ql.hw.create('usart1')
ql.hw.create('gpioa')
ql.hw.create('afio')
ql.hw.create('spi2')
ql.hw.create('dma1').watch()
ql.debugger = True
ql.run()
I'd expect either GDB to intercept the interrupt OR it just being handled internally by the firmware as it does when running without the debugger (without 'ql.debugger = True' the firmware just runs normally).
However, the debugger appears to think the target exited as no exception is raised, and then throws an Exception due to the MCU not having an exit code:
[+] Received interrupt: 0x2
Traceback (most recent call last):
...
File "/home/user/.local/lib/python3.10/site-packages/qiling/core.py", line 586, in run
debugger.run()
File "/home/user/.local/lib/python3.10/site-packages/qiling/debugger/gdb/gdb.py", line 767, in run
reply = handler(subcmd.decode(ENCODING))
File "/home/user/.local/lib/python3.10/site-packages/qiling/debugger/gdb/gdb.py", line 655, in handle_v
return handle_c('')
File "/home/user/.local/lib/python3.10/site-packages/qiling/debugger/gdb/gdb.py", line 243, in handle_c
reply = f'W{self.ql.os.exit_code:02x}'
AttributeError: 'QlOsMcu' object has no attribute 'exit_code'
I tried letting the handle_c method run 'self.gdb.resume_emu()' in a loop, but then the interrupt is just looping and the firmware gets stuck. Wasn't able to find the code responsible for dropping out of the emulator loop when an interrupt is raised in debug mode versus non-debug mode. In any case the interrupt shouldn't be interpreted as the target exiting. I'd prefer the interrupt handler is simply called within the firmware as normal without dropping to the debugger; I can always put a bp on the handler address if needed.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in qiling/debugger/gdb/gdb.py, tracing run(), handle_c(), and the interrupt path after the reported Received interrupt message. Review qiling/debugger/gdb/xml/cortex_m and the setup_remap context in hw/hw.py. Done means an STM32 interrupt can be handled by the firmware during GDB execution without being treated as target exit or requiring an MCU exit_code.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- devtools, embedded-iot, reverse-engineering
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100