From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from h2828900.stratoserver.net (unknown [IPv6:2a01:238:4297:d900:4603:3bf9:5939:b0a9]) by sourceware.org (Postfix) with ESMTP id 80E5A385DC2B for ; Wed, 18 Aug 2021 20:31:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 80E5A385DC2B Received: from [192.168.0.251] (ip5f5bdfd1.dynamic.kabel-deutschland.de [95.91.223.209]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: max@schneidersoft.net) by h2828900.stratoserver.net (Postfix) with ESMTPSA id A576434047B; Wed, 18 Aug 2021 22:31:41 +0200 (CEST) Message-ID: Subject: Re: GDB call and p func() on embedded target From: Maximilian Schneider To: Simon Marchi , gdb@sourceware.org Date: Wed, 18 Aug 2021 21:31:41 +0100 In-Reply-To: <774bfb5f-7117-911f-58fc-c884ce92993c@polymtl.ca> References: <10f7f78c-ac4d-b54f-b250-c915203c6f47@polymtl.ca> <6c9c737155f28ea174457f4a0eb41e1e408a73b3.camel@schneidersoft.net> <774bfb5f-7117-911f-58fc-c884ce92993c@polymtl.ca> Content-Type: text/plain; charset="UTF-8" User-Agent: Evolution 3.30.5-1.1 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-1.6 required=5.0 tests=BAYES_00, KAM_DMARC_STATUS, SPF_FAIL, SPF_HELO_NONE, TXREP autolearn=no autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gdb@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Aug 2021 20:31:53 -0000 On Sun, 2021-08-15 at 21:14 -0400, Simon Marchi wrote: > On 2021-08-14 11:54 a.m., Maximilian Schneider wrote: > > 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? > > The execution out of the manual function call isn't expected to end > "just like that", with a return. Normally, when the called function > returns, it should return to some code (the dummy stack frame) that > generates some exception, so that GDB gets back control. How this is > done varies from arch to arch. This is where it happens: > > > https://gitlab.com/gnutools/binutils-gdb/-/blob/master/gdb/infcall.c#L956-1012 > > For ARM, it seems like gdbarch_call_dummy_location uses the default > AT_ENTRY_POINT, meaning that GDB puts a breakpoint at the address > returned by entry_point_address(), and sets up the stack frame > created > to call Init to return there. Maybe with your executable the entry > point returns 0, and that's why you see frame 1 having pc == 0? > > Simon Thank you for the great information! Turns out it was the start address. Since gdb is setting up a frame to call my function and then return to the start address; it is no wonder that it does not work. 0 is neither ram not flash so sw breakpoints will not work there. HW breakpoints probably won't work there either. I added -e 0x2000000 to the compilation to set an explicit entry point and huzza it works :) If gdb is already putting code on the stack to call my function why not implement a sw breakpoint there? Why return to start? Why does gdb care at all what the start address is? Since this is an external loader that lives in ram and has no main() i don't see what the point of the entry point is. M.