This is the mail archive of the
gdb@sourceware.org
mailing list for the GDB project.
Re: Ensure correct symbol-file when attaching to a (remote) process
- From: Raphael Zulliger <zulliger at indel dot ch>
- To: Pedro Alves <palves at redhat dot com>
- Cc: gdb at sourceware dot org
- Date: Tue, 29 Jan 2013 04:51:15 +0100
- Subject: Re: Ensure correct symbol-file when attaching to a (remote) process
- References: <50D3FC31.1020103@indel.ch> <20121221161114.GA32638@host2.jankratochvil.net> <201212211917.qBLJH6Il028006@new.toad.com> <50E474E3.7050605@redhat.com> <51073F73.5000905@indel.ch>
On 01/29/2013 04:18 AM, Raphael Zulliger wrote:
I agree.
(--build-id is a very interesting feature which I was not aware of.
Thanks for that hint Jan)
In our scenario, our GDB stub could get that build-id from the running
target: Our embedded systems provides a variable read/write mechanism
accessible by the stub. Moreover, the embedded system could be made
aware of the address of the build-id by introducing variables around
the .note.gnu.build-id section in the linker script.
Here's the solution we came up with. Unfortunately, the solution is not
very GDB-like mainly because the lack of time to create high quality GDB
patches. But at least I want to share our (low-end) solution with you.
(Note: I'm definitely not saying that this is the ideal solution! It's
just good enough for our use cases.)
I post this message because of two purposes:
1. As a reference if someone is searching the web
2. To check if someone comes up with a better solution for reading the
build-id out from an elf file
Here's what we've done in order to read the build-id from within our
C/C++ code of our embedded software:
- We pass "-Wl,--build-id" to the linker invocation
- We extended the linker script by:
.note : {
PROVIDE (__NOTE_BUILDID_BEGIN__ = .);
*(.note.gnu.build-id)
PROVIDE (__NOTE_BUILDID_END__ = .);
} > ram
- In the C/C++ code we have something like this:
extern unsigned int __NOTE_BUILDID_BEGIN__;
extern unsigned int __NOTE_BUILDID_END__;
With these two variables at hand, we are able to propagate the build-id
to our GDB-stub by our own "PC to embedded system communication".
- On the GDB side, we hacked some python code to read the build-id out
from the ELF file:
def GetBuildId():
BuildId = ""
# we only ever have 1 ELF file (or 0 in case of a user error):
for file in gdb.objfiles():
cmd = 'objdump -s -j .note ' + file.filename
p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output = p.stdout.read()
for line in output.splitlines():
if len(line) > 0 and line[0] == ' ':
for entry in line.split()[1:5]:
BuildId = BuildId + entry
return BuildId
This is definitely no high-end code, but it does its job. Among others,
It's potentially unstable if objdump changes it's output format... I
searched the web for a better way of getting the content of a certain
section out from an object file, but couldn't find a solution. If
someone knows about a GDB/Python interface for doing so, I would
definitely like to hear about it!
The build-id read out from the ELF file will then be sent to our GDB
stub in a non-GDB way (again some kind of home-made communication, which
we'd already in use). Our GDB stub finally compares the build-id read
from the ELF file with the one read from the embedded system and can
compare them for equality.
Raphael