This is the mail archive of the cygwin mailing list for the Cygwin project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: python aborts

On 7/25/2013 12:11 AM, Daniel Colascione wrote:
> On 7/24/2013 11:55 PM, Daniel Colascione wrote:
>> Does that help at all?  I only started seeing this problem after I recompiled
>> _wp.dll using gcc 4.7.3.
> Actually, this problem looks a lot like
> neither Python nor
> _wp links dynamically to libgcc, but cygsqlite3-0.dll does.

And this is a very nasty bug; Eli's analysis is correct. Say we have modules Foo
and Bar. Foo links against shared libgcc, but Bar does not. Now, if we load Foo,
load Bar, unload Foo, then unload Bar, then Foo's initialization code finds
libgcc and registers itself with it, but Foo's deinitializaton code doesn't find
libgcc, tries to instead unregister with Foo's internal data structures, finds
them uninitialized, and aborts. No wonder changing Python module order around
makes the problem go away for a little while.

The right fix for libgcc looks something like this:

--- config/i386/cygming-crtbegin.c.orig 2013-07-25 00:07:35.000000000 -0800
+++ config/i386/cygming-crtbegin.c      2013-07-25 00:33:11.000000000 -0800
@@ -82,6 +82,8 @@
 extern void __gcc_register_frame (void);
 extern void __gcc_deregister_frame (void);

+static HANDLE libgcc_dll;
 __gcc_register_frame (void)
@@ -94,8 +96,11 @@
   void (*register_frame_fn) (const void *, struct object *);
   HANDLE h = GetModuleHandle (LIBGCC_SONAME);
   if (h)
-    register_frame_fn = (void (*) (const void *, struct object *))
-                       GetProcAddress (h, "__register_frame_info");
+    {
+      libgcc_dll = LoadLibrary (LIBGCC_SONAME); /* Hold reference */
+      register_frame_fn = (void (*) (const void *, struct object *))
+       GetProcAddress (h, "__register_frame_info");
+    }
     register_frame_fn = __register_frame_info;
   if (register_frame_fn)
@@ -124,13 +129,16 @@
   void *  (*deregister_frame_fn) (const void *);
-  HANDLE h = GetModuleHandle (LIBGCC_SONAME);
-  if (h)
+  if (libgcc_dll)
     deregister_frame_fn = (void* (*) (const void *))
-                         GetProcAddress (libgcc_dl, "__deregister_frame_info");
+      GetProcAddress (libgcc_dll, "__deregister_frame_info");
     deregister_frame_fn = __deregister_frame_info;
   if (deregister_frame_fn)
      deregister_frame_fn (__EH_FRAME_BEGIN__);
+  if (libgcc_dll)
+    FreeLibrary (libgcc_dll);

The problem is that this code is baked into every module compiled with the buggy
libgcc. You have to recompile the world to fix it for good --- except if shared
libgcc is pinned in memory.

Attachment: signature.asc
Description: OpenPGP digital signature

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]