Re: GDB call and p func() on embedded target
Maximilian Schneider via Gdb <[email protected]>
| Newsgroups | gmane.comp.gdb.devel |
|---|---|
| Message-ID | <[email protected]> |
Hello, Some more information: I'm working on an stm32l475. using openocd like so: openocd -v Open On-Chip Debugger 0.10.0+dev-g436782b (2019-03-05-19:20) openocd -f interface/stlink-v2-1.cfg -f target/stm32l4x.cfg -d3 And the executable I debug is compiled like this: arm-none-eabi-gcc -Wall -Werror -Tscript.ld -Wl,-n,-N -nostartfiles -ggdb -g -nostdlib -FPIC -FPIE -mcpu=cortex-m4 $(INCLUDES) $(DEFINES) src/loader.c -o loader.elf I use a linker script to put the code section into RAM. I should als mention the gdb version: arm-none-eabi-gdb -v GNU gdb (7.12-6+9+b2) 7.12.0.20161007-git I will try compiling the latest gdb from source, and debug it a little later. In the mean time I can demonstrate gdb is creating stack frames. Maybe you can spot something wrong with them? (gdb) set debug infrun 1 (gdb) p Init() infrun: clear_proceed_status_thread (Remote target) infrun: proceed (addr=0x20000aac, signal=GDB_SIGNAL_0) infrun: resume (step=0, signal=GDB_SIGNAL_0), trap_expected=0, current thread [Remote target] at 0x20000aac infrun: infrun_async(1) infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun: -1.0.0 [Thread 0], infrun: status->kind = ignore infrun: TARGET_WAITKIND_IGNORE infrun: prepare_to_wait * just sits here * I don't see any comments about creating a stack frame. But gdb definately creates one. I can inspect the stack frame after the call is made eg: I place a breakpoint in Init. and use p Init() twice. (gdb) p Init() ... (gdb) p Init() .. (gdb) info frame Stack level 0, frame at 0x2000ffe0: pc = 0x20000ab2 in Init (src/loader.c:718); saved pc = 0x0 called by frame at 0x2000ffe0 source language c. Arglist at 0x2000ffd0, args: Locals at 0x2000ffd0, Previous frame's sp is 0x2000ffe0 Saved registers: r7 at 0x2000ffd8, lr at 0x2000ffdc (gdb) info frame 1 Stack frame at 0x2000ffe0: pc = 0x0; saved pc = 0x20000ab2 called by frame at 0x2000fff8, caller of frame at 0x2000ffe0 Arglist at unknown address. Locals at unknown address, Previous frame's sp is 0x2000ffe8 (gdb) info symbol 0x20000ab2 Init + 6 in section PrgCode This is creating two stack frames as expected, and I can step the inner function. When I step through the return there is a pop instruction that restores the PC from the stack frame and execution resumes in the calee. What is pc= vs saved pc=? Is it relevant that pc=0x0? Regards, M. On Sat, 2021-08-14 at 09:05 -0400, Simon Marchi wrote: > On 2021-08-14 6:28 a.m., Maximilian Schneider via Gdb wrote: > > Hello, > > > > I am trying to call a function from withing a gdb debugging session > > on > > an embedded target. However gdb never returns and when i stop it > > manually the program counter is in a strange place. It appears that > > gdb > > is not able to catch the return, and is continuing execution from > > before the core was halted... > > > > assume the function I want to call has prototype int32_t > > Init(void); > > > > If I set the pc manually I can step throught the function until the > > return without a problem. > > > > I can even set a breakpoint on Init and then use p Init(). The > > breakpoint will fire and I can step throught the code manually. > > > > eg. > > > > target remote localhost:3333 > > monitor reset halt > > monitor reset init > > file loader.elf > > load loader.elf > > set $sp=0x20010000 > > set $pc=&Init > > b Init > > p Init() > > n > > n > > n > > ... > > > > However without the breakpoint gdb never returns. > > Is this a known problem? Is there a workaround? > > > > Some background: > > The purpose of this entire excercise is to arrive at a tool/set of > > scripts that can be used to load and execute arbitrary code from > > RAM, > > to fi. manipulate external memories or run tests. > > > > Regards, > > M > > Hi Maximilian, > > I don't think there would be a way to solve this other than debugging > GDB itself, stepping in the call_function_by_hand_dummy function to > understand what it does, how it sets up the dummy stack frame, what > technique it uses to put the breakpoint that should lead to the > function > call being completed, etc.. And also running with "set debug infrun > 1" > and possibly stepping through handle_inferior_event, to see why GDB > doesn't realize the function call isn't over. > > The call_function_by_hand_dummy really lacks debug prints, making it > hard to debug when it goes wrong. I was debugging another function > call > issue the other day, and thought to myself that it would be a good > time > to add some. > > Also, inferior function call has a lot of arch-specific components to > it, so if you could mention the arch you are working on, it could > help > narrow things down. > > Simon >