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 1932E386545E for ; Wed, 31 Mar 2021 13:00:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 1932E386545E 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 12VD03K9024852 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 31 Mar 2021 09:00:08 -0400 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 12VD03K9024852 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 E36481E590; Wed, 31 Mar 2021 09:00:02 -0400 (EDT) Subject: Re: Remote query for structure layout To: David Blaikie Cc: Tim Newsome , gdb References: <6b00bbbe-1400-7f11-bdcf-811595bf8e31@polymtl.ca> <1c8fec3c-0d7e-d133-bf88-adaf764473f1@polymtl.ca> From: Simon Marchi Message-ID: <4f5e4de2-035d-a1eb-69ef-bb4144ce82de@polymtl.ca> Date: Wed, 31 Mar 2021 09:00:02 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.7.1 MIME-Version: 1.0 In-Reply-To: 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 Wed, 31 Mar 2021 13:00:03 +0000 X-Spam-Status: No, score=-4.2 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.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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, 31 Mar 2021 13:00:14 -0000 On 2021-03-30 11:27 p.m., David Blaikie wrote: > (let me know if I'm just being an unhelpful bystander here - I clearly > don't have a lot of context) I think it is interesting. If people are not interested they can just skip reading this thread :). > On Tue, Mar 30, 2021 at 5:16 PM Simon Marchi wrote: >> >> On 2021-03-30 6:44 p.m., David Blaikie wrote: >>> If it's "just" some user-code, is there a variable of the desired type being declared around the function call? >> >> AFAIK, this type wouldn't be used by the FreeRTOS code at all, so no. >> Again, here's my understanding, hopefully it's close enough to the >> reality. >> >> When a trap occurs, FreeRTOS saves the current task's register values on >> the task's stack, using some arch-specific assembly code. For example, >> for RISC-V: >> >> https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/534eba66ce4a5bda45d5edeeb81ac5a3cf6d0df8/portable/GCC/RISC-V/portASM.S#L121 > > Ah, OK. So this is part of signal handling - so it's not part of the > code that's compiled into the user's program, for instance... not even > in some system library linked in, necessarily, I guess? It is part of "user code". Wih "big" OSes (e.g. Linux), the OS is compiled on its own and the user programs are compiled separately. With embedded RTOSes (at least those I worked with), it's just one big program. Your user code includes and calls FreeRTOS functions to spawn to tasks. >> The way these registers are pushed is an implementation detail of >> FreeRTOS. And we can imagine that it can vary depending on the >> compile-time FreeRTOS configuration, > > I guess in the worst case it could be totally dynamic - it could pick > a different layout each time. Yes, if it wanted to be really annoying :). > (guess a side question: How's this different from other systems? I > don't know how other/more common systems handle registers during > signals) I think Linux does the same, pushing the registers (and some information about the signal) on the thread's stack before calling a signal handler. The layout is defined by the ucontext structure, exposed in the Linux ABI: https://github.com/torvalds/linux/blob/master/arch/riscv/include/uapi/asm/ucontext.h GDB hardcodes that layout here: https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=gdb/riscv-linux-tdep.c;h=ca97a60128ffe681766e7e1600d3f24048bf1f68;hb=HEAD#l103 Being exposed by the Linux kernel and part of this ABI, this structure is not likely to change. That makes it reasonable to hardcode it. >> which OpenOCD doesn't know about. >> >> To get register values of scheduled out tasks, OpenOCD needs to >> interpret these register values from the tasks' stacks. >> >> So Tim's suggestion is: have FreeRTOS declare a structure that has the >> exact layout as the saved registers on the stack: >> >> struct freertos_saved_regs { >> int x1; >> int x5; >> int x6; >> ... >> }; >> >> Consumers could read that structure's layout from the DWARF info, and >> read the register values based on that. That would be a lot more robust >> than hard-coding in the consumers how FreeRTOS stores things. > > If practical experience has shown the hard-coding is not > stable/reliable (than FreeRTOS does change its strategy from time to > time - but it's always constant for any given build of the FreeRTOS) I > guess. My guess is that FreeRTOS does not change it that often, there's not reason to. But it can vary from build to build due to compile-time configuration of FreeRTOS (i.e. include or exclude support for using some particular register). An external observer such as OpenOCD does not have access to the compile-time configuration that was used to build FreeRTOS, so it's difficult to know what the layout used by this particular build is. > But I'm not sure where FreeRTOS would expose this structure to user > code - it's not like there's a system library header that user code > must include... There is, any code using FreeRTOS will include FreeRTOS.h. You can see FreeRTOS more like a library than an OS. FreeRTOS is not involved at all until the user program calls functions like xTaskCreate to create some tasks and calls vTaskStartScheduler to hand over control to FreeRTOS. So if the structure was declared somewhere in the port's include file, it would necessarily be seen by some CUs (those that invoke FreeRTOS functions). >> However, since that struct would never actually be used by FreeRTOS' >> code, the compiler won't emit it. Hence the need to find a way to force >> the compiler to include it in the DWARF. >> >> Does that clarify the situation? > > Somewhat - any lack of understanding is just my ignorance in this > field/area in general, to be clear. (I'm also not a core gdb > developer, so I'm not the sort of person you have to convince of > anything - just a curious bystander trying to understand/maybe offer > some insightful suggestions (I predominantly work on LLVM's debug info > emission, so that's my background/connection)) Well, since it's related to debug info emission, it could land on your plate at some point, it's good that you have some context. Simon