C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Interceptor Function (preserve stack and all registers)

From: Thiago Macieira <thiago_at_[hidden]>
Date: Thu, 01 Aug 2024 11:59:13 -0700
On Thursday 1 August 2024 07:22:19 GMT-7 Frederick Virchanza Gotham via Std-
Proposals wrote:
> First draft paper on interceptor functions:
>
> http://www.virjacode.com/papers/interceptor.htm
>
> In the future I need to add loads more stuff, specifically what Lorand
> said about Haskell.
> I corrected the assembler errors pointed out to me by Thiago.

Please describe how such functionality could be used, using only the Standard
Library or with content you provide in the paper.

Hint: you can't.

You're not explaining how the interceptor function gets installed. It appears
to be automatic by just having it declared, which is obviously not the case.
There needs to be more steps to make it happen.

In your motivation section, please explain why this should be in the standard,
not as a functionality provided by the toolchain and debugger. If I wanted to
log all calls to a specific function, besides ltrace I have already mentioned,
it would be easy to put a breakpoint in the function in question and run some
debugger script to print what I needed. Given that those things exist, please
improve your motivation with additional reasons beyond what's there.

I don't think your solution for reentrancy is a good one. I recommend instead
requiring the runtime to allocate a per-thread shadow stack (like the Indirect
Branch Tracking feature of Intel CET requires) and push data into it. This
removes the need for the developer to estimate anything and pushes the problem
to the implementation, which can possibly also be tuned at runtime. Further,
this improves space utilisation because then multiple intercepting functions
in the same thread can share the space, instead of each one having reserved
its worst case scenario. And I don't think the requirement to update the
runtime would be a deal breaker, since we are talking about a debugging
feature. Developers debug using modern tools.

Your possible implementation for x86 does both too much and too little. Why
are you preserving some non-preserved registers and not others? Either you
save the entire context (using XSAVE, which requires dynamic buffer sizes and
CPUID detection) or you limit yourself to what the ABI requires. This is not
merely an implementation-defined behaviour because it impinges on whether you
can intercept any function (or for that matter any instruction) or whether you
can only intercept at function call boundaries that respect ABI. That is, is
this feature expected to be able to intercept calls between two different
routines written in assembly that don't obey the ABI?

If you do turn this into interception of ABI-compliant function calls, then
you should add some non-normative words about how a compiler would implement
interception of different ABIs, as an extension. That is, for Windows 32-bit
i386, interception of __cdecl, __thiscall, __stdcall and __syscall.

I think you got carried away with what you could do and didn't pay attention
to what you needed to do.

Given the lack of means to install this, the impossibility of describing the
restricted conditions under which it applies, the fragility of the solution
and the availability of much less fragile means for most work, I don't think
this belongs in the Standard.

-- 
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
  Principal Engineer - Intel DCAI Platform & System Engineering

Received on 2024-08-01 18:59:19