Hi Jon,
On Sun, 9 Nov 2025 16:30:18 +0000
Jon Turney wrote:
> On 09/11/2025 09:02, Takashi Yano wrote:
> > Hi Mark,
> >
> > On Sun, 9 Nov 2025 00:09:07 -0800
> > Mark Geisert wrote:
> >> Hi Takashi,
> >>
> >> On 11/4/2025 8:58 PM, Takashi Yano wrote:
> >>> On Tue, 28 Oct 2025 20:48:40 +0900
> >>> Takashi Yano wrote:
> >>>> Takashi Yano (2):
> >>>> Cygwin: dll_init: Call __cxa_finalize() for DLL_LOAD even in
> >>>> exit_state
> >>>> Cygwin: dll_init: Don't call dll::init() twice for DLL_LOAD.
> >>>>
> >>>> winsup/cygwin/dll_init.cc | 8 +++++---
> >>>> 1 file changed, 5 insertions(+), 3 deletions(-)
> >>>>
> >>>> --
> >>>> 2.51.0
> >>>>
> >>>
> >>> Could anyone please review if these patches make sense?
> >>
> >> The patches look fine to me. Do you happen to have an STC that
> >> demonstrates to you the issue is fixed with your patch?
> >
> > Thanks for reviewing. The STC is the attachment files in
> > https://cygwin.com/pipermail/cygwin/2025-October/258919.html
>
> I'm finding it pretty hard to reason about what the possible
> combinations that should be considered are.
>
> Like, what is the spanning set? I guess we have:
>
> 1. A single DLL X, directly linked with by executable
> 2. A single DLL X, dlopened and dlclosed (subcases where it does this
> during constructor/destructors and otherwise?)
> 3. As above, but X is directly linked with Y
> 4. As above, but X is dlopens/dlcloses Y
> 5. more???
>
> If I understood all that, then maybe I'd have some suggestions about how
> the comments can be written to explain why what it's doing is the right
> thing in the various situations.
>
> I guess it's possible to extend that STC to cover all those?
Thanks for the advice.
I have extended the STC to cover all the cases:
main-dll2 { direct | dlopen | dlopen-wo-dlclose }
dll2-dll3 { direct | dlopen | dlopen-in-ctor | dlopen-wo-dlclose |
dlopen-in-ctor-wo-dlclose }
, that is, 15 test cases in total.
I confirmed that all the test cases work as expected.
Please try new STC attached. (Just run 'make test')
As for comments in the source code and commit message, please
let me consider a bit.
Thanks.
--
Takashi Yano <[email protected]>
#include <stdio.h>
#include <dlfcn.h>
static void *dll3;
static void dllinit(void) __attribute__((constructor));
static void dllinit(void)
{
printf("+++++++++++++++++++++++++++++\n");
#if DLLB == 2
dll3 = dlopen("dll3.dll", RTLD_LOCAL|RTLD_NOW);
#endif
}
static void dllquit(void) __attribute__((destructor));
static void dllquit(void)
{
printf("-----------------------------\n");
#if DLLB == 2 && !defined(NO_DLCLOSE)
dlclose(dll3);
#endif
}
void func2()
{
void (*func)(void);
#if DLLB == 0
extern void func3(void);
func = func3;
#endif
#if DLLB == 1
dll3 = dlopen("dll3.dll", RTLD_LOCAL|RTLD_NOW);
#endif
#if DLLB != 0
func = dlsym(dll3, "func3");
#endif
func();
#if DLLB == 1 && !defined(NO_DLCLOSE)
dlclose(dll3);
#endif
}
#include <stdio.h>
static void dllinit(void) __attribute__((constructor));
static void dllinit(void)
{
printf("++++++++++++++\n");
}
static void dllquit(void) __attribute__((destructor));
static void dllquit(void)
{
printf("--------------\n");
}
void func3()
{
printf("oooooooooooooo\n");
}
#include <dlfcn.h>
int main()
{
void (*func)(void);
#if DLLA == 0
extern void func2();
func = func2;
#endif
#if DLLA != 0
void *dll2 = dlopen("dll2_1.dll", RTLD_LOCAL|RTLD_NOW);
func = dlsym(dll2, "func2");
#endif
func();
#if DLLA == 1 && !defined(NO_DLCLOSE)
dlclose(dll2);
#endif
return 0;
}
all: case0 case1 case2 case3 case4 case5 case6 case7 case8 case9 case10 case11
case12 case13 case14
case0: main.c dll2_0.dll
$(CC) -DDLLA=0 main.c dll2_0.dll -o case0
case1: main.c dll2_1.dll
$(CC) -DDLLA=0 main.c dll2_1.dll -o case1
case2: main.c dll2_2.dll
$(CC) -DDLLA=0 main.c dll2_2.dll -o case2
case3: main.c dll2_1n.dll
$(CC) -DDLLA=0 main.c dll2_1n.dll -o case3
case4: main.c dll2_2n.dll
$(CC) -DDLLA=0 main.c dll2_2n.dll -o case4
case5: main.c dll2_0.dll
$(CC) -DDLLA=1 main.c dll2_0.dll -o case5
case6: main.c dll2_1.dll
$(CC) -DDLLA=1 main.c dll2_1.dll -o case6
case7: main.c dll2_2.dll
$(CC) -DDLLA=1 main.c dll2_2.dll -o case7
case8: main.c dll2_1.dll
$(CC) -DDLLA=1 main.c dll2_1n.dll -o case8
case9: main.c dll2_2.dll
$(CC) -DDLLA=1 main.c dll2_2n.dll -o case9
case10: main.c dll2_0.dll
$(CC) -DDLLA=1 -DNO_DLCLOSE main.c dll2_0.dll -o case10
case11: main.c dll2_1.dll
$(CC) -DDLLA=1 -DNO_DLCLOSE main.c dll2_1.dll -o case11
case12: main.c dll2_2.dll
$(CC) -DDLLA=1 -DNO_DLCLOSE main.c dll2_2.dll -o case12
case13: main.c dll2_1.dll
$(CC) -DDLLA=1 -DNO_DLCLOSE main.c dll2_1n.dll -o case13
case14: main.c dll2_2.dll
$(CC) -DDLLA=1 -DNO_DLCLOSE main.c dll2_2n.dll -o case14
dll2_0.dll: dll2.c dll3.dll
$(CC) -DDLLB=0 dll2.c dll3.dll -shared -o dll2_0.dll
dll2_1.dll: dll2.c
$(CC) -DDLLB=1 dll2.c -shared -o dll2_1.dll
dll2_2.dll: dll2.c
$(CC) -DDLLB=2 dll2.c -shared -o dll2_2.dll
dll2_1n.dll: dll2.c
$(CC) -DDLLB=1 -DNO_DLCLOSE dll2.c -shared -o dll2_1n.dll
dll2_2n.dll: dll2.c
$(CC) -DDLLB=2 -DNO_DLCLOSE dll2.c -shared -o dll2_2n.dll
dll3.dll: dll3.c
$(CC) dll3.c -shared -o dll3.dll
test: all
./case0
./case1
./case2
./case3
./case4
./case5
./case6
./case7
./case8
./case9
./case10
./case11
./case12
./case13
./case14
clean:
$(RM) -f *.exe *.dll