Mercurial > cpython-lru_cache-weakref
view Python/dynload_mac.c @ 22621:830c829a7eb2 legacy-trunk
Fix an issue that was reported in but unrelated to the main problem of
SF bug 535905 (Evil Trashcan and GC interaction).
The SETLOCAL() macro should not DECREF the local variable in-place and
then store the new value; it should copy the old value to a temporary
value, then store the new value, and then DECREF the temporary value.
This is because it is possible that during the DECREF the frame is
accessed by other code (e.g. a __del__ method or gc.collect()) and the
variable would be pointing to already-freed memory.
BUGFIX CANDIDATE!
| author | Guido van Rossum <guido@python.org> |
|---|---|
| date | Thu, 28 Mar 2002 20:17:52 +0000 |
| parents | 379fc66f4c96 |
| children | ed28b9752f8d |
line wrap: on
line source
/* Support for dynamic loading of extension modules */ #include "Python.h" #include "importdl.h" #include <Aliases.h> #include <CodeFragments.h> #ifdef USE_GUSI1 #include "TFileSpec.h" /* for Path2FSSpec() */ #endif #include <Files.h> #include <TextUtils.h> #include "macdefs.h" #include "macglue.h" const struct filedescr _PyImport_DynLoadFiletab[] = { {".slb", "rb", C_EXTENSION}, #ifdef __CFM68K__ {".CFM68K.slb", "rb", C_EXTENSION}, #else #if TARGET_API_MAC_CARBON {".carbon.slb", "rb", C_EXTENSION}, #else {".ppc.slb", "rb", C_EXTENSION}, #endif #endif {0, 0} }; dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname, const char *pathname, FILE *fp) { dl_funcptr p; char funcname[258]; /* ** Dynamic loading of CFM shared libraries on the Mac. The ** code has become more convoluted than it was, because we ** want to be able to put multiple modules in a single ** file. For this reason, we have to determine the fragment ** name, and we cannot use the library entry point but we have ** to locate the correct init routine "by hand". */ FSSpec libspec; CFragConnectionID connID; Ptr mainAddr; Str255 errMessage; OSErr err; #ifndef USE_GUSI1 Boolean isfolder, didsomething; #endif char buf[512]; Str63 fragname; Ptr symAddr; CFragSymbolClass class; /* First resolve any aliases to find the real file */ #ifdef USE_GUSI1 err = Path2FSSpec(pathname, &libspec); #else c2pstrcpy((unsigned char *)buf, pathname); (void)FSMakeFSSpec(0, 0, (unsigned char *)buf, &libspec); err = ResolveAliasFile(&libspec, 1, &isfolder, &didsomething); #endif if ( err ) { PyOS_snprintf(buf, sizeof(buf), "%.200s: %.200s", pathname, PyMac_StrError(err)); PyErr_SetString(PyExc_ImportError, buf); return NULL; } /* Next, determine the fragment name, by stripping '.slb' and 'module' */ memcpy(fragname+1, libspec.name+1, libspec.name[0]); fragname[0] = libspec.name[0]; if( strncmp((char *)(fragname+1+fragname[0]-4), ".slb", 4) == 0 ) fragname[0] -= 4; if ( strncmp((char *)(fragname+1+fragname[0]-6), "module", 6) == 0 ) fragname[0] -= 6; /* Load the fragment (or return the connID if it is already loaded */ err = GetDiskFragment(&libspec, 0, 0, fragname, kLoadCFrag, &connID, &mainAddr, errMessage); if ( err == cfragImportTooOldErr || err == cfragImportTooNewErr ) { /* ** Special-case code: if PythonCore is too old or too new this means ** the dynamic module was meant for a different Python. */ if (errMessage[0] == 10 && strncmp((char *)errMessage+1, "PythonCore", 10) == 0 ) { PyOS_snprintf(buf, sizeof(buf), "Dynamic module was built for %s version of MacPython", (err == cfragImportTooOldErr ? "a newer" : "an older")); PyErr_SetString(PyExc_ImportError, buf); return NULL; } } if ( err ) { PyOS_snprintf(buf, sizeof(buf), "%.*s: %.200s", errMessage[0], errMessage+1, PyMac_StrError(err)); PyErr_SetString(PyExc_ImportError, buf); return NULL; } /* Locate the address of the correct init function */ PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname); err = FindSymbol(connID, Pstring(funcname), &symAddr, &class); if ( err ) { PyOS_snprintf(buf, sizeof(buf), "%s: %.200s", funcname, PyMac_StrError(err)); PyErr_SetString(PyExc_ImportError, buf); return NULL; } p = (dl_funcptr)symAddr; return p; }
