[lldb-dev] RFC: siginfo reading/writing support
Pavel Labath via lldb-dev
lldb-dev at lists.llvm.org
Wed Jan 12 04:28:17 PST 2022
I kinda like the cleanliness (of the design, not the implementation) of
a $siginfo variable, but you're right that implementing it would be
tricky (I guess we'd have to write the struct info the process memory
somewhere and then read it back when the expression completes).
I don't expect that users will frequently want to modify the siginfo
structure. I think the typical use case would be to inspect the struct
fields (maybe in a script -- we have one user wanting to do that) to
understand more about the nature of the stop/crash.
With that in mind, I don't have a problem with a separate command, but I
don't think that the "platform" subtree is a good fit for this. I mean,
I am sure the (internal) Platform class will be involved in interpreting
the data, but all of the platform _commands_ have something to do with
the system as a whole (moving files around, listing processes, etc.) and
not a specific process. I think this would belong under the "thread"
subtree, since the signal is tied to a specific thread.
Due to the scripting use case, I am also interested in being able to
inspect the siginfo struct through the SB API -- the expression approach
would (kinda) make that possible, while a brand new command doesn't
(without extra work). So, I started thinking whether this be exposed
there. We already kinda expose the si_signo field via
GetStopReasonDataAtIndex(0) (and it even happens to be the first siginfo
field), but I don't think we would want to expose all fields in that manner.
This then lead me to SBThread::GetStopReasonExtendedInfoAsJSON. What is
this meant to contain? Could we put the signal info there. If yes, then
the natural command-line way of retrieving this would be the "thread
info" command, and we would need to add any new commands.
This wouldn't solve the problem of writing to the siginfo struct, but I
am not sure if this is a use case Michał is actually trying to solve
right now (?) If it is then, maybe this could be done through a separate
command, as we currently lack the ability to resume a process/thread
with a specific signal ("process signal" does something slightly
different). It could either be brand new command, or integrated into the
existing process/thread continue commands. (thread continue --signal
SIGFOO => "continue with SIGFOO"; thread continue --siginfo $47 =>
continue with siginfo in $47 ???)
pl
On 12/01/2022 01:07, Jim Ingham via lldb-dev wrote:
> I would not do this with the expression parser.
>
> First off, the expression parser doesn’t know how to do anything JIT code that will run directly in the target. So if:
>
> (lldb) expr $signinfo.some_field = 10
>
> doesn’t resolve to some $siginfo structure in real memory with a real type such that clang can calculate the offset of the field “some_field” and write to it to make the change, then this wouldn’t be a natural fit in the current expression parser. I’m guessing this is not the case, since you fetch this field through ptrace calls in the stub.
>
> And the expression parser is enough of a beast already that we don’t want to add complexity to it without good reason.
>
> We also don’t have any other instances of lldb injected $variables that we use for various purposes. I’m not in favor of introducing them as they end up being pretty undiscoverable….
>
> Why not something like:
>
> (lldb) platform signinfo read [-field field_name]
>
> Without the field name it would print the full siginfo, or you can list fields one by one with the —field argument.
>
> And then make the write a raw command like:
>
> (lldb) platform signinfo write -field name expression
>
> The platform is a natural place for this, it is the agent that knows about all the details of the system your target is running on, so it would know what access you have to siginfo for the target system.
>
> Having the argument write use expressions to produce the new value for the field would get you most of the value of introducing a virtual variable into the expression parser, since:
>
> (lldb) pl si w -f some_field <complex expression>
>
> Is the same as you would get with the proposed $siginfo:
>
> (lldb) expr $siginfo.some_field = <complex expression>
>
> You could also implement the write command as a raw command like:
>
> (lldb)platform siginfo write —field some_field <complex expression>
>
> Which has the up side that people wouldn’t need to quote their expressions, but the down side that you could only change one field at a time.
>
> This would also mean “apropos siginfo” would turn up the commands, as would a casual scan through the command tree. So the feature would be pretty discoverable.
>
> The only things this would make inconvenient are if you wanted to pass the value of a signinfo field to some function call or do something like:
>
> $signinfo.some_field += 5
>
> These don’t seem very common operations, and if you needed you could always do this with scripting, since the result from “platform siginfo read -field name” would be the value, so you could write a little script to grab the value and insert it into the desired expression and run that.
>
> One of the advantages of having a command tree is has a few top level nodes and organizes the commands under them is that adding new commands doesn’t clutter up the top level of the command tree, and so you should feel free to add new commands where they fit into the hierarchy rather than trying to slide them into some other command, like using the expression parser.
>
> Jim
>
>
>
>> On Jan 11, 2022, at 7:48 AM, Ted Woodward via lldb-dev <lldb-dev at lists.llvm.org> wrote:
>>
>>
>> You should use Hg for this instead of Hc. Hc is used for step/continue, while Hg is used for everything else.
>>
>>
>>> -----Original Message-----
>>> From: lldb-dev <lldb-dev-bounces at lists.llvm.org> On Behalf Of Michal Górny
>>> via lldb-dev
>>> Sent: Tuesday, January 11, 2022 6:38 AM
>>> To: lldb-dev at lists.llvm.org
>>> Subject: [lldb-dev] RFC: siginfo reading/writing support
>>>
>>> Hello,
>>>
>>> TL;DR: I'd like to implement at least partial support for reading/writing siginfo
>>> via LLDB. I can't think of a better approach than copying the GDB's idea of
>>> "magical" $_siginfo variable that works through the expression evaluator. I'd
>>> like to know your opinion/ideas.
>>>
>>>
>>> POSIX defines a siginfo_t structure that is used to pass additional signal
>>> information -- such as more detailed signal code, faulting memory address in
>>> case of SIGSEGV or PID of the child process in case of SIGCHLD. LLDB already
>>> uses ptrace(2) to obtain this information and use it internally but it doesn't
>>> expose it to the user.
>>>
>>> The GDB Remote Serial protocol provides the ability to read/write siginfo via
>>> qXfer:siginfo:... packets [1]. GDB exposes this information to the user via a
>>> special $_siginfo variable [2].
>>>
>>> A few things to note:
>>>
>>> 1. Some targets (e.g. Linux, NetBSD) support overwriting siginfo, some (e.g.
>>> FreeBSD) only reading.
>>>
>>> 2. Siginfo is generally associated with a single thread, so the packets should
>>> be combined with respective thread selection (Hg or Hc?).
>>>
>>> 3. The exact type of siginfo_t differs per platform (POSIX specifies a minimal
>>> subset).
>>>
>>>
>>> My rough idea right now is to follow GDB here. While using "$_siginfo"
>>> may seem hacky, it has the nice advantage that it can easily support all
>>> different siginfo_t structures used by various platforms.
>>>
>>> The plan would be to:
>>>
>>> 1. Implement the qXfer:siginfo:... packets in lldb-server, and add tests to
>>> them.
>>>
>>> 2. Implement support for "$_siginfo" in the client (I suppose this means
>>> hacking on expression evaluator).
>>>
>>> 3. (Optionally) implement hardcoded siginfo_t definitions for common
>>> platforms to make things work without debug info.
>>>
>>> WDYT?
>>>
>>>
>>> [1]
>>> https://www.sourceware.org/gdb/onlinedocs/gdb/General-Query-
>>> Packets.html#qXfer-siginfo-read
>>> [2] https://sourceware.org/gdb/current/onlinedocs/gdb.html#Signals
>>>
>>>
>>> --
>>> Best regards,
>>> Michał Górny
>>>
>>>
>>> _______________________________________________
>>> lldb-dev mailing list
>>> lldb-dev at lists.llvm.org
>>> https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
>> _______________________________________________
>> lldb-dev mailing list
>> lldb-dev at lists.llvm.org
>> https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
>
> _______________________________________________
> lldb-dev mailing list
> lldb-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
More information about the lldb-dev
mailing list