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

Reply via email to