Open dmik opened 7 years ago
This is a test case:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <wait.h>
int main()
{
int status;
printf("Parent\n");
switch (fork())
{
case -1:
perror("fork failed");
exit(-1);
case 0:
{
printf("Child\n");
return 0;
}
}
if (wait(&status) == -1)
{
perror("wait failed");
return 1;
}
if (!WIFEXITED(status) || WEXITSTATUS(status))
{
printf("child crashed or returned non-zero (status %x)\n", status);
return 1;
}
return 0;
}
With GCC 6.1.0, I get: [U:\DEV]gcc -Zexe test.c [U:\DEV]test Parent Child
Well, did you try the LOGCHK version of LIBC with that?
Yup.... [u:\dev]copy e:\usr\lib\libc066.logchk libc066.dll E:\usr\lib\libc066.logchk => U:\DEV\libc066.dll 1 file copied
[u:\dev]copy c:\PROGRAMS\firefox\firefox!.exe test!l.exe C:\PROGRAMS\firefox\firefox!.exe => U:\DEV\test!l.exe 1 file copied
[u:\dev]test!l.exe
[u:\dev]test!l.exe 2>&1 | tee log Parent Child Parent
Well, it's not enough to copy it over, you need BEGINLIBPATH/LIBPATHSTRICT=T (since there is a normal copy of LIBC066 in memory which will always be used otherwise).
yep, hence the use of run! to start it in a new session...
That's strange. Can you try GCC 4.9.2 instead?
gcc 4.9.2 gives the same results here. How are you compiling the example. Optimisation related?
Nothing special, just gcc -Zomf test.c
. But ok, it turns out that the reason is that I have a slightly different LIBC LOGCHK build than the RPM one — there I have different names for LIBC shared mem and mutex names because otherwise it tries to write to use the structures of the already loaded normal LIBC and it screws some things up like fork() under some circumstances. So using a completely different build somehow seems to screw the GCC DLL. I need to do a few other tests to decide what to do with this.
While playing with
libc066.logchk
DLL, I found that GCC1.DLL causes an assertion (most likely throughgcc_assert
) during the forked child termination. The test program is attached. This is the call stack (EXCEPTQ install is needed together with LIBC_BREAKPOINT_ABORT=1 to see that, it's omitted in the test):The above addresses in GCC1 are most likely
__deregister_frame
and__deregister_frame_info
(which calls__deregister_frame_info_bases
which callsgcc_assert
which callsabort
which issuesint 3
ifLIBC_BREAKPOINT_ABORT
is set).Although
emx-ctordtor.c
contains some fork callbacks, it looks like the constructor/destructor chain is not properly aligned in the forked child so it asserts on a NULL pointer (presumably,libgcc\unwind-dw2-fde.c
line 216, a debug of GCC with symbols s necessary to tell more).