On Sun, 25 Apr 2021, Liu Hao wrote:


--

I think this might be ok, but I tried looking at how MSVC behaves with this with regard to registering the function within exe vs dll, and whether the dll or the exe calls quick_atexit. Here's my test setup:

lib.c:

#include <stdlib.h>
#include <stdio.h>

static void at_quick_exit_func(void) {
    printf("lib at_quick_exit_func\n");
    fflush(stdout);
}
static void atexit_func(void) {
    printf("lib atexit_func\n");
    fflush(stdout);
}
__declspec(dllexport) void libfunc(void) {
    atexit(atexit_func);
    at_quick_exit(at_quick_exit_func);
}
__declspec(dllexport) void libfunc_exit1(void) {
    exit(0);
}
__declspec(dllexport) void libfunc_exit2(void) {
    _exit(0);
}
__declspec(dllexport) void libfunc_exit3(void) {
    quick_exit(0);
}


main.c:

#include <stdlib.h>
#include <stdio.h>

static void at_quick_exit_func(void) {
    printf("main at_quick_exit_func\n");
    fflush(stdout);
}
static void atexit_func(void) {
    printf("main atexit_func\n");
    fflush(stdout);
}
void reg(void) {
    atexit(atexit_func);
    at_quick_exit(at_quick_exit_func);
}

void libfunc(void);
void libfunc_exit1(void);
void libfunc_exit2(void);
void libfunc_exit3(void);

int main(int argc, char* argv[]) {
    reg();
    libfunc();
    if (argc > 1) {
        int val = atoi(argv[1]);
        switch (val) {
        case 0: exit(0); break;
        case 1: _exit(0); break;
        case 2: quick_exit(0); break;
        case 3: libfunc_exit1(); break;
        case 4: libfunc_exit2(); break;
        case 5: libfunc_exit3(); break;
        }
    }
    return 0;
}


The exact behaviour for cases 3-5 differ between whether the two are linked dynamically or statically against the CRT. I'm not sure if all the nuances are worth mimicing though. (A function registered with at_quick_exit within the DLL isn't called when quick_exit is called, regardless of whether the main executable or the DLL calls it.)

However - if a DLL does at_quick_exit, and the DLL later is unloaded, we might have an issue if we go with this kind of patch... But the MSVC behaviour doesn't seem entirely consistent either?

Regarding your patch, it fails to build with clang due to function type mismatches - at_quick_exit takes an _PVFV, not an _onexit_t. (I also see that ucrtbase_compat.c currently is wrong about this, it declares _crt_atexit with the wrong type of parameter. I can send a standalone patch that fixes that.)

// Martin



_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to