I am a maintainer of
Win32::API. There are some assembly tricks that can be used to detect certain kinds of C prototype mistakes and other C stack problems. I am thinking of adding one such kind of check to Win32::API (
Win32::api v0.75 issue importing DLL is encouragement it is needed). Microsoft offers a feature called
Run-Time Error Checks, which when on (almost always used only in "debug" mode images), will throw up a GUI box that says "The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention." A different but similar technique is
http://en.wikipedia.org/wiki/Buffer_overflow_protection.
What do you think Win32::API should do if it finds out that *AFTER* calling a C function, that the C function was called with the wrong prototype and it might have seen uninitialized memory, and random things might have been written to the caller's C stack? Currently I have (in psuedo C)
struct { DWORD register_ebp; DWORD register_esp) debugInfo = {ebp,
+ esp};
RaiseException(STATUS_BAD_STACK, EXCEPTION_NONCONTINUABLE, 2, &deb
+ugInfo);
/* this TerminateProcess can only be reached with a C debugger and
+ trapping the "untrappable" exception above */
TerminateProcess(GetCurrentProcess(), STATUS_BAD_STACK);
Would a Perl's C croak/die be preferred? But that can be caught, but should such an error be possible to catch? or swallowing a potential C stack corruption (AKA stack buffer overflow) and resuming execution never sane?
But someone can argue, croak does a
http://en.wikipedia.org/wiki/Longjmp which rewinds the stack, and any corrupt C autos will be skiped/gone/deleted/never used again, and also Win32::API uses alot of alloca (safety margin for the corruption to land in, C functions rarely have more than a dozen parameters right so the corrupting write wont land on anything sensitive?), so a croak is safe %99.99999 of the time and it is perfectly fine to resume execution in the OS thread. In any case, someone can say that anyone who can set the C prototype given to Win32::API already has rooted the system and low level C stack 5p1o7z are redundant, or a Perl process with Win32::API in it, should never be exposed to a hostile client since the Win32::API module is a security breach by definition and concept.
Or just call C library fprintf(stderr, ...) and exit() and bypass Perl, but dont throw up a cryptic Windows crash box to the user of Win32::API?
Or call Perl's my_exit(), but that uses longjmp
http://perl5.git.perl.org/perl.git/blob/93f31ee9fb6e815cac5df15822755aa4d75c91a9:/perl.c#l4986 and can resume execution in earlier portion/some far up caller in the C stack, and runs Perl code (object dtors and END blocks).