#1055 tcl core dumps (sigsegv) on exit under unix (sequent dynix/p

obsolete: 8.2.1
closed-fixed
nobody
2
2001-04-18
2000-10-26
Anonymous
No

OriginalBugID: 3373 Bug
Version: 8.2.1
SubmitDate: '1999-11-05'
LastModified: '1999-11-30'
Severity: MED
Status: Released
Submitter: techsupp
ChangedBy: hobbs
RelatedBugIDs: 2560
OS: Other
OSVersion: Dynix/Ptx-4.0
FixedDate: '1999-11-30'
FixedInVersion: 8.2.3
ClosedDate: '2000-10-25'

Name:

Jackson McCann

Comments:

The patch supplied cures the problem under dynix/ptx but is probably a

bit heavy handed. A better approach might be to allow a package to mark

itself as unloadable? Or to take advantage of the fact that atexit

functions are called in the reverse of the order they are registered in.

Moving the package unload to its own atexit function which is registered

as part of the interpreters startup?

ReproducibleScript:

/*

** The following tcl extension demostrates the problem. Compile it as

a

** loadable shared library. It registers an atexit function but because

** tcl now unloads the shared library as part of its exit processing

the

** atexit function causes the memory violation.

*/

#include <tcl.h>

static void my_exit(void)

{

printf("Goodbye\n") ;

}

static int _wrap_Times_Two(ClientData clientData,

Tcl_Interp *interp,

int objc,

Tcl_Obj *CONST objv[]) {

int _result;

unsigned long _arg0;

long _arg1 = 0;

Tcl_Obj * tcl_result;

int tempint;

clientData = clientData; objv = objv;

tcl_result = Tcl_GetObjResult(interp);

if ((objc < 2) || (objc > 3))

{

Tcl_SetStringObj(tcl_result,

"Wrong # args. Tuxedo::Tpbegin timeout ?flags?

",

-1);

return TCL_ERROR;

}

if (Tcl_GetIntFromObj(interp,objv[1],&tempint) == TCL_ERROR)

return TCL_ERROR;

_arg0 = (unsigned long ) tempint;

if (objc >2)

{

if (Tcl_GetIntFromObj(interp,objv[2],&tempint) == TCL_ERROR)

return TCL_ERROR;

_arg1 = (long ) tempint;

}

_result = _arg0 * 2 ;

tcl_result = Tcl_GetObjResult(interp);

Tcl_SetIntObj(tcl_result,(long) _result);

return TCL_OK;

}

int Times_two_Init (Tcl_Interp *interp) {

if (interp == 0)

return TCL_ERROR;

Tcl_Eval(interp,"namespace eval Tuxedo { }");

if (Tcl_InitStubs(interp, "8.0", 0) == NULL) {

return TCL_ERROR ;

}

Tcl_CreateObjCommand(interp,

"Times_Two",

_wrap_Times_Two,

(ClientData) NULL,

(Tcl_CmdDeleteProc *) NULL);

if (atexit(my_exit) != 0 )

{

printf("No atexit\n") ;

return TCL_ERROR ;

}

return TCL_OK;

}

ObservedBehavior:

Core dump on exit if a shared library that registers an atexit function

is loaded.

DesiredBehavior:

No core dump

Patch:

*** ../generic/tclLoad.c Mon Oct 11 12:05:43 1999

--- ../generic/tclLoad.c.orig Mon Oct 11 12:05:39 1999

***************

*** 645,663 ****

while (firstPackagePtr != NULL) {

pkgPtr = firstPackagePtr;

firstPackagePtr = pkgPtr->nextPtr;

!

! /*

! ** Don't automatically remove shared libraries from memory at shutdown.

! ** There may be a reference to code in the shared libary in an atexit()

! ** exit handler

! */

!

! /*

! if (pkgPtr->fileName[0] != '\0') {

! TclpUnloadFile(pkgPtr->clientData);

}

- */

-

ckfree(pkgPtr->fileName);

ckfree(pkgPtr->packageName);

ckfree((char *) pkgPtr);

--- 645,653 ----

while (firstPackagePtr != NULL) {

pkgPtr = firstPackagePtr;

firstPackagePtr = pkgPtr->nextPtr;

! if (pkgPtr->fileName[0] != '\0') {

! TclpUnloadFile(pkgPtr->clientData);

}

ckfree(pkgPtr->fileName);

ckfree(pkgPtr->packageName);

ckfree((char *) pkgPtr);

PatchFiles:

generic/tclLoad.c

8.2.3 was changed to not unload any DLLs when finalizing,
allowing for code like the (bad) use of atexit above to function
without a core. 8.3 should be improved to allow the user to
specify whether the dll should be unloaded or not. Users should
use Tcl_CreateExitHandler from Tcl instead of atexit.
-- 11/30/1999 hobbs

Discussion

  • Brent B. Welch
    Brent B. Welch
    2000-10-26

    • priority: 5 --> 2
    • status: open --> closed-fixed
     
  • Don Porter
    Don Porter
    2001-04-18

    • labels: 104246 --> 02. Event Loops