[PATCH] Linux: Access memory even if threads are running
Pedro Alves
pedro@palves.net
Thu Jul 1 17:30:29 GMT 2021
On 2021-07-01 6:08 p.m., Luis Machado wrote:
> On 7/1/21 1:49 PM, Pedro Alves wrote:
>> On 2021-07-01 4:49 p.m., Luis Machado wrote:
>>> On 7/1/21 11:34 AM, Pedro Alves wrote:
>>>> On 2021-07-01 2:18 p.m., Luis Machado wrote:
>>>>> Out of curiosity... Why not attempt to lift the restriction of PTRACE not being able to read/write memory of running threads? Sounds like that would've been useful.
>>>>
>>>> PTRACE_PEEKTEXT/PTRACE_POKETEXT can only read/write a word at a time, while with /proc
>>>> there's no practical limit on how much you can read/write with one syscall. We
>>>> were already preferring /proc if the access was more than a word. We'd still want to have
>>>> the /proc code working for efficiency, and the new code that now tries to open a different lwp if
>>>> the thread exits would still be required. I'm not seeing how changing ptrace would help
>>>> in practice. (And then it would only work with newer kernels, of course.)
>>>
>>> Right. I get the motivation for this particular use case.
>>>
>>> Lifting this restriction would be an improvement to the ptrace interface in general. I'm thinking beyond reading individual words of memory, but reading registers, memory tags etc. I'm assuming any ptrace request for a running thread will result in a failure. Is that the case?
>>>
>>
>> Yes, most ptrace operations require a stopped tracee. From man ptrace:
>>
>> "(...) For requests other than PTRACE_ATTACH, PTRACE_SEIZE, PTRACE_INTERRUPT, and PTRACE_KILL, the tracee must be
>> stopped."
>>
>
> I see. Thanks.
>
> So even though memory reads/writes will now be allowed, reading registers/memory tags or doing any other sort of ptrace request for data won't work.
>
> For example, if we want to validate memory tags for a particular tagged pointer, we won't be able to do so because the memory will be available, but the tags won't be.
>
> I guess it would be a similar situation if you have a variable that lives in a register, right? Or a variable that lives in a vector register that has its size determined by another register (SVE vector length).
GDB won't even try to read registers off of running threads:
(gdb) info registers
Selected thread is running.
(gdb) p $rax
Selected thread is running.
Variables that live in registers only make sense in the context of some frame. But if the
thread is running, what frame would that be? Between thinking about reading the register,
and actually reading it, a zillion instructions will have executed. Might be useful to be able
to get a snapshot of registers for sampling where the program is (basically read the PC) with
minimal disturbance (though the kernel would still need to interrupt the thread for a brief
moment, I believe), but I'm not sure I'd let the user that in the normal case. It seems more
confusing than helpful. I think that the only registers that make sense reading normally
are global system registers shared by all threads. I don't think SVE registers fit
in that model?
I don't know how memory tags work, I have not followed that thread.
>
> In this context, I guess I'm missing the main motivation for enabling this feature like this instead of fixing ptrace. I understand that fixing ptrace is a much more complicated issue, but still, it sounds like a more long term solution.
>
I think you're still missing my point quoted above -- even if you made ptrace work with running thread,
you'd still want to work with /proc for reads/writes larger than a word, and so all the code I added is
still desirable. There's no "instead of". If someone makes ptrace work with running threads, it won't
make the new code obsolete.
I did not consider changing ptrace simply because I had no use for reading registers off of
running threads.
Pedro Alves
More information about the Gdb-patches
mailing list