Winelib MFC app crashes after printing

Eric Frias efrias at syncad.com
Wed Jun 1 10:35:39 CDT 2005


Eugene Aksenov wrote:
> I have a small MFC app ported to winelib which uses MFC compiled with winelib. Really, it is just an App-Wizard generated application.
> I always have a crash of the application after printing. The page is printed ok but after that the app crashes. 
> [...]
> Did anybody meet a problem like that ? Is it MFC that has some impact here ? Thanks a lot for any hints.

I've run into this bug & fixed it.  I just was never confident enough in 
my fix to get around to submitting it.

The problem you're seeing is most likely because you have a C++ 
application.  When wine prints something via lpr, it forks off a child 
process to do the printing.  Instead of doing exec("lpr") as most other 
programs do, wine does a system("lpr"); exit();  The normal exit causes 
the child process to execute global destructors, which the 'exec' 
wouldn't.  If the global destructors free memory that is also used by 
the parent process (which is probably common), the parent process will 
quickly crash.

Try the attached patch and see if it fixes your problem.  I think it's 
mostly correct for linux, solaris, and hp.  We'd need to check the 
behavior of system() on other platforms to make sure it's consistent. 
On Solaris, it looks like there are circumstances when system() will 
invoke 'ksh' instead of 'sh', but I hope wine doesn't need to worry too 
much about that little detail.

Eric
-------------- next part --------------
Index: printdrv.c
===================================================================
--- printdrv.c	(.../vendor/wine/current/dlls/gdi/printdrv.c)	(revision 30779)
+++ printdrv.c	(.../trunk/wine/dlls/gdi/printdrv.c)	(revision 30779)
@@ -516,9 +516,13 @@
             signal( SIGPIPE, SIG_DFL );
             signal( SIGCHLD, SIG_DFL );
 
-            system(psCmdP);
+#if defined(__hpux) || (defined(__sun) && defined(__SVR4))
+            execl("/usr/bin/sh", "sh", "-c", psCmdP, 0);
+#else
+            execl("/bin/sh", "sh", "-c", psCmdP, 0);
+#endif
+            /* If the exec fails, we'll just take our chances and exit */
             exit(0);
-
         }
         close (fds[0]);
         fd = fds[1];


More information about the wine-devel mailing list