Jean Brouwers added the comment:

Attached is an updated dlibtest.c file.  It prints a message in the con-
/destructor functions and if that fails it calls _exit(9).

Compile and run it as before and check the exit status.  If the latter 
is 9 or 011, a printf error occurred indicating e.g. that stdout was 
closed or something similar.

This version can also be used with gdb, either by pre-loading the 
dlibtest.so library within gdb or before invoking gdb.  To preload the 
library within gdb (on Linux) use

   gdb  .../python
   (gdb) set environment LD_PRELOAD ./dlibtest.so
   (gdb) run
   .....

or to preload before gdb use

   setenv LD_PRELOAD ./dlibtest.so
   gdb .../python
   (gdb) run
   .....

Lastly, my previous observations about this issue were clearly a "trompe 
d'oeil", especially my statement that PyImport_Cleanup never returned.  
The missing print statements *after* the PyImport_Cleanup call are 
simply due to printf errors, and nothing else ;-)

Added file: http://bugs.python.org/file8625/dlibtest.c

__________________________________
Tracker <[EMAIL PROTECTED]>
<http://bugs.python.org/issue1329>
__________________________________
#include "stdio.h"
#include "string.h"
#include "unistd.h"

#ifndef __GNUC__
# error requires the GNU compiler
#endif

extern const char* __progname;

/* call printf() only if inside python binary */
static void
_printf (const char* fmt, const char* arg1, const char* arg2)
{
    if (!strcmp("python", __progname)) {
        if (printf(fmt, arg1, arg2) < 0) {
            _exit(9);  /* stdout closed? */
        }
    }
}


#if 0  /* pick this ... */

static void  __attribute__((constructor))  /* called on main() */
_ctor (void)
{
    _printf("*** %s called in %s ...\n", "ctor", __progname);
}

static void __attribute__((destructor))  /* called on exit() */
_dtor (void)
{
    _printf("*** %s called in %s ...\n", "dtor", __progname);
}


#else  /* ... or this case */

static void  /* called on Python exit */
_dtor (void)
{
    _printf("*** %s called in %s ...\n", "dtor", __progname);
}

/* the weak attribute prevents unresolved symbol errors */
extern int Py_AtExit (void(*func)(void)) __attribute__((weak));

static void  __attribute__((constructor))  /* called on main() */
_ctor (void)
{
    _printf("*** %s called in %s ...\n", "ctor", __progname);
    if (Py_AtExit) {
       _printf("*** %s %s\n", "Py_AtExit", (Py_AtExit(_dtor) < 0 ? "failed!" : 
"OK"));
    }
}

#endif


/* =====================================================

Build this file into a shared library, then pre-load
that library with the Python binary as follows.

On Linux, compile as

    gcc -o dlibtest.os -c -m32 -Wall -Werror -fPIC dlibtest.c
    gcc -o dlibtest.so -m32 -ldl -shared dlibtest.os

and then run

    env LD_PRELOAD=./dlibtest.so  .../python


On MacOS X, compile as

    gcc -o dlibtest.os -c -Wall -Werror -march=i686 -fPIC dlibtest.c
    gcc -o dlibtest.dylib -undefined dynamic_lookup -lpthread -dynamiclib 
dlibtest.os

and run

   env DYLD_INSERT_LIBRARIES=./dlibtest.dylib  .../python.exe


To preload the library within gdb (on Linux) use

   gdb  .../python
   (gdb) set environment LD_PRELOAD ./dlibtest.so
   (gdb) run
   .....

or use

   setenv LD_PRELOAD ./dlibtest.so
   gdb .../python
   (gdb) run
   .....


After Ctrl-D two messages should have been printed, but 3.0a1
prints only the first one.  An exist status is 9 or 011 indicates
that a printf error occurred.



Here is a log from Linux with my 3.0a1 and 2.51 builds and
with 2.3.4 included with the Linux distro:

$ gcc -o dlibtest.os -c -m32 -Wall -Werror -fPIC dlibtest.c
$ gcc -o dlibtest.so -m32 -ldl -shared dlibtest.os

$ env LD_PRELOAD=./dlibtest.so ~/Python-3.0a1/python 
*** ctor called ...
Python 3.0a1 (py3k, Oct 26 2007, 09:45:17) 
[GCC 3.4.6 20060404 (Red Hat 3.4.6-8)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 

$ env LD_PRELOAD=./dlibtest.so ~/Python-2.5.1/python
*** ctor called ...
Python 2.5.1 (r251:54863, Oct 22 2007, 16:19:11) 
[GCC 3.4.6 20060404 (Red Hat 3.4.6-8)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 
*** dtor called ...

$ env LD_PRELOAD=./dlibtest.so /usr/bin/python
*** ctor called ...
Python 2.3.4 (#1, May  2 2007, 19:26:00) 
[GCC 3.4.6 20060404 (Red Hat 3.4.6-8)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 
*** dtor called ...


Similarly on MacOS X with Python 2.3.5 distributed by Apple:

% env DYLD_INSERT_LIBRARIES=./dlibtest.dylib ~/Python-3.0a1/python.exe
*** ctor called ...
Python 3.0a1 (py3k, Oct 25 2007, 14:55:57) 
[GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> ^D

% env DYLD_INSERT_LIBRARIES=./dlibtest.dylib ~/Python-2.5.1/python.exe
*** ctor called ...
Python 2.5.1 (r251:54863, Oct 22 2007, 16:18:08) 
[GCC 4.0.1 (Apple Computer, Inc. build 5341)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> ^D
*** dtor called ...

% env DYLD_INSERT_LIBRARIES=./dlibtest.dylib /usr/bin/python
*** ctor called ...
Python 2.3.5 (#1, Jan 13 2006, 20:13:11) 
[GCC 4.0.1 (Apple Computer, Inc. build 5250)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> ^D
*** dtor called ...


/Jean Brouwers  <[EMAIL PROTECTED]>


PS) For more details on the con/destructor attributes, see the GNU
    gcc documentation at

    <http://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Function-Attributes.html>

    See also Apple's documentation DynamicLibrary.pdf which
    contains some excellent examples plus special MacOS X
    features.  E.g. c/dtor must be ZPRIVATE and a static
    ctor can have main-like argc, argv and envp arguments!

 ===================================================== */

_______________________________________________
Python-bugs-list mailing list 
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to