Support synthesizing the siginfo_t type from the Platform plugin.
This type is going to be used by LLDB client to process the raw siginfo
data received from lldb-server without the necessity of relying
on target's debug info being present.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
My current test program is:
#!/usr/bin/env python import lldb raw_data = b'\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00up\n\x00\xe8\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' lldb.SBDebugger.Initialize() try: dbg = lldb.SBDebugger.Create() try: t = dbg.CreateTarget("/home/mgorny/git/llvm-project/build/a.out") assert t typ = list(t.FindTypes("siginfo_t"))[0] assert typ typ2 = t.GetPlatform().GetSiginfoType(t) assert typ2 data = lldb.SBData() data2 = lldb.SBData() error = lldb.SBError() data.SetData(error, raw_data, lldb.eByteOrderLittle, 8) print(t.CreateValueFromData("siginfo", data, typ)) print(t.CreateValueFromData("siginfo2", data, typ2)) finally: lldb.SBDebugger.Destroy(dbg) finally: lldb.SBDebugger.Terminate()
Hmm, maybe for the sub-structs, it'd be better to use TypeSystemClang::CreateStructForIdentifier().
Use CreateStructForIdentifier() whenever possible. Describe the remaining union members.
Open question: do we care for 100% correct SPARC support? Given that it has different _sigfault layout, it adds some complexity while LLDB doesn't seem to support SPARC at all.
Initial PoC unit test — the idea is to verify field offsets and sizes against known values taken from real siginfo_t.
Put the common test code into a common init function, add tests for armv7, arm64, i386, ppc64le.
Simplify the tests to use dotted member notation for field lookup. Make the test utility generate exact test code.
Turn PlatformLinuxTest into a more generic PlatformSiginfoTest, to improve code reuse between platforms. Start preparing for testing FreeBSD.
Combine the tests for various 32-bit and 64-bit arches, as they have the same offset-size pairs. Instead of repeating them, just iterate over the list of arches.
Adding Alex for the plugin dependency aspect. I don't think this dep is wrong (it's pretty hard to pretend we don't at least have a C language), but he may want to say something about this.
The patch itself is somewhat repetitive, but otherwise seems ok.
I am a bit curious about the __lldb prefix. I'm wondering if there's a way to avoid having it, while still maintaining isolation from any type with the same name coming from the debug info. I'm thinking about putting it in some kind of an anonymous namespace or something... Does anyone know if that works?
lldb/source/API/SBPlatform.cpp | ||
---|---|---|
672 ↗ | (On Diff #402208) | ?? |
lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp | ||
323 | we don't | |
lldb/unittests/Platform/PlatformSiginfoTest.cpp | ||
84 | drop c_str() | |
110 | Other platform APIs seem to take an ArchSpec or even a Triple, so doing that would be more consistent *and* make your job here easier. |
The GetSiginfoType API seems awkward to me. It requires I get the data itself from some other source and then cast it to this type myself. I'm assuming in the fullness of time, there will be a GetSiginfoData call, and then I have to put the two together? The only reason I can see to have separate "GetType" and "GetData" calls is if there's some useful way to get the data blob that doesn't go through lldb.
After all, if we had:
SBValue SBThread::GetSiginfoValue();
API you can still get the type and data back out of the SBValue if you needed them. But I am pretty sure most uses will be to query the values of its child members, which makes the value returning API more convenient.
At the lldb_private layer, it's fine to separate the two, but when you go to present this to the outside world through commands or API's we try to keep the API set more compact.
I think we need to have a way to express types that the base platform has so we can present them in a structured way to users. Formally, you could express this by saying that we need a "platform language" reflecting how that platform vends it's API's at the lowest level. This would have been Pascal for classic MacOS way back in the day, and maybe Lisp for Lisp machines. But IRL all the platforms we are likely to deal with express their lowest level system API's in C, so it seems okay to have that be an implicit assumption till we come across a system that we want to support and for which C isn't one of the low level system languages.
The patch itself is somewhat repetitive, but otherwise seems ok.
I am a bit curious about the __lldb prefix. I'm wondering if there's a way to avoid having it, while still maintaining isolation from any type with the same name coming from the debug info. I'm thinking about putting it in some kind of an anonymous namespace or something... Does anyone know if that works?
This will be the actual type of an SBValue, as is the case in other instances where we've made up types, so users will see this type if they look closely. So it should be clear from the name that this is just an artificial type lldb made up. __lldb_whatever expresses that pretty clearly, but I'm worried some reasonable looking name in an anonymous namespace would send users off on a wild goose chase.
lldb/source/API/SBPlatform.cpp | ||
---|---|---|
672 ↗ | (On Diff #402208) | Sorry, debug leftover ;-). |
Hmm, I think I've exposed it via SBPlatform because originally I planned on writing the tests in Python. However, it ended up being tested through unittests after all, so I think I can remove that part. Lemme try.
In the end, you will want some SB API exposing this information so users can do something with it. I think returning the SBValue for the Thread is the right way to go. I see you're doing that in https://reviews.llvm.org/D118055.
Thanks for the review. I'm going to wait with the merging until the other patch is reviewed, in case there are any API changes required here.
we don't