From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id CB11D3861C50 for ; Mon, 16 Aug 2021 01:14:56 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org CB11D3861C50 Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 17G1EnrR009721 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sun, 15 Aug 2021 21:14:54 -0400 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 17G1EnrR009721 Received: from [10.0.0.11] (192-222-157-6.qc.cable.ebox.net [192.222.157.6]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id 0E2631E79C; Sun, 15 Aug 2021 21:14:48 -0400 (EDT) Subject: Re: GDB call and p func() on embedded target To: Maximilian Schneider , gdb@sourceware.org References: <10f7f78c-ac4d-b54f-b250-c915203c6f47@polymtl.ca> <6c9c737155f28ea174457f4a0eb41e1e408a73b3.camel@schneidersoft.net> From: Simon Marchi Message-ID: <774bfb5f-7117-911f-58fc-c884ce92993c@polymtl.ca> Date: Sun, 15 Aug 2021 21:14:48 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.13.0 MIME-Version: 1.0 In-Reply-To: <6c9c737155f28ea174457f4a0eb41e1e408a73b3.camel@schneidersoft.net> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Mon, 16 Aug 2021 01:14:49 +0000 X-Spam-Status: No, score=-5.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, NICE_REPLY_A, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham 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: Mon, 16 Aug 2021 01:15:07 -0000 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