While I see some use for standardization for Zhao YunShan's compile time interception, yours is just a technique for debuggers (human or programs).
On development machines those control flow safeguards would be turned off.
If you want to write functions, which receive back the program flow, why do you call it goto in the interceptor function?
What is done under the hood, does not matter.
The compiler would just set breakoints and know, when to jump back and forth.
Beside INT 3, there are debug registers DR0-DR3 or page traps. For profiling calls without performance loss there are additional convenient features on modern CPUs (but they would not run any interceptor function).
It is all highly platform specific.
It could go into debug APIs of the operating systems.
The ABI is not out of scope for operating systems to know.
So the correct registers would be saved.
Nothing suitable for standardization for C++.
-----Ursprüngliche Nachricht-----
Von: Frederick Virchanza Gotham via Std-Proposals <std-proposals@lists.isocpp.org>
Gesendet: Mo 04.05.2026 09:25
Betreff: Re: [std-proposals] interceptor functions (tested and working on x86_64)
An: std-proposals@lists.isocpp.org;
CC: Frederick Virchanza Gotham <cauldwell.thomas@gmail.com>;
I’m thinking of going a step further with this. Up until now, we can intercept on the way in:[[intercept]] void Func(void) noexcept{DoLogging();goto -> std::fprintf;}But it would also be possible to intercept on the way out, meaning we could lock and unlock a mutex. Ideally we would be able to do the following:std::mutex m;[[intercept]] void Func(void) noexcept{std::lock_guard mylock(m);goto -> std::fprintf;}That would be quite complicated to implement though, as under the hood you’d need to make it do something like:std::mutex m;[[intercept]] void Func(void) noexcept{::new( some_where ) std::lock_guard(m);goto -> std::fprintf;some_where->~lock_guard<std::mutex>();}Getting the target function to jump back to the interceptor is the easy part – you only need to change the return address on the stack (or the link register on aarch64). I’ve heard rumours of something called ‘Control-flow Enforcement Technology’ which would prevent this on x86_64, but MS-Windows can disable it with 'SetProcessMitigationPolicy', or 'prctl' on Linux. The tricky part is where to put the ‘lock_guard’, as it cannot go on the stack – remember the stack must remain intact for the jump. I suppose it could go in a thread_local variable. Realistically I think the first ‘proof of concept’ implementation would need to look something like the following:std::mutex m;[[intercept]] void Func(void) noexcept{m.lock();goto -> std::fprintf<-- [](void *p){ m.unlock(); return p; };}So basically the above snippet would do five things:(1) lock the mutex(2) store the original return address somewhere (perhaps in a thread_local variable)(3) alter the return address on the stack to the entry point of the lambda body(4) jump to the target functionI think I’d be able to implement the above snippet in the GNU compiler without too much hassle; basically it would work as follows:goto -> target_address <-- address_of_outward_interceptorWe can argue about the syntax another day, I’m only concerned about getting it working for now. An alternative syntax could be:std::jump_to( target_address, address_of_outward_interceptor );And if the second argument is ‘nullptr’ then there’s no outward interception.I would find this extremely useful for debugging. Let's say we suspect that a library has a race condition or data race that is causing it to malfunction -- well we can just wrap every function call in a mutex-locking-and-unlocking to see if that fixes it.-- Std-Proposals mailing list Std-Proposals@lists.isocpp.org https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals