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
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.