Ticket UUID: | 960414 | |||
Title: | exit causes segmentation violation with Oratcl extension | |||
Type: | Bug | Version: | obsolete: 8.5a2 | |
Submitter: | tmh | Created on: | 2004-05-25 21:13:47 | |
Subsystem: | 16. Commands A-H | Assigned To: | hobbs | |
Priority: | 5 Medium | Severity: | ||
Status: | Closed | Last Modified: | 2005-02-17 08:52:26 | |
Resolution: | Duplicate | Closed By: | hobbs | |
Closed on: | 2005-02-17 01:52:26 | |||
Description: |
Something has changed in the exit handling of Tcl since the 8.4.6 release. This change causes a segmentation violation when using the Oratcl extension. This is similar to a previous Bug ID # 2560. At issue is that the Oracle library (that cannot be changed) that is linked dynamically at runtime with Oratcl, has atexit() calls embedded in the library. These calls fire when tcl finally calls exit(). If the Oratcl extension library is unloaded before the exit() happens, then the atexit() can no longer reference the symbols in the Oratcl library that called the oracle library. I am listing this as a Tcl Bug because, Oratcl has not been changed. This works just fine in Tcl 8.4.6. jumpgate: [75] > gdb /opt/tcl8.5a2d/bin/tclsh8.5 GNU gdb 4.18 Copyright 1998 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "sparc-sun-solaris2.7"... (gdb) run Starting program: /opt/tcl8.5a2d/bin/tclsh8.5 % package require Oratcl 4.2 % set lda [oralogon t/b@c] oralogon: invalid username/password; logon denied % exit Program received signal SIGSEGV, Segmentation fault. Cannot access memory at address 0xfe842e54. Maybe there is a way to preserve the library so that it is not unloaded, but I cannot tell from the documentation how to do that. Also, Oratcl does use an exit handler. If I add an exit(0) to my exit handler, the core dump goes away, but none of the other things in Tcl_Finalize occur. | |||
User Comments: |
hobbs added on 2005-02-17 08:52:25:
Logged In: YES user_id=72656 dup as 1011715 tmh added on 2005-02-17 02:04:14: Logged In: YES user_id=92123 New version of Oratcl does not suffer from this behavior so I am canceling the bug report. tmh added on 2004-06-01 00:38:44: Logged In: YES user_id=92123 Ok I agree that package require is the wrong place to tweak. I am wondering if this is not related to TIP 100. I do not have a Oratcl_Unload proc defined, so I do not know why the oratcl library is being unloaded. Do you have any comments on the patch to tclLoadDl.c that I have uploaded. I really would like to figure this out before Tcl 8.5 is released stable as this will be a nightmare to support. Thanks Todd dgp added on 2004-06-01 00:30:18: Logged In: YES user_id=80530 [package require] is the wrong place to add tweaks to the operation of [load] and [unload]. tmh added on 2004-05-30 22:56:02: File Added - 88949: diff Logged In: YES user_id=92123 I have found a solution but the impact on others, I cannot address... It would be nice if there was an API to turn on/off thischange for particular packages . Something like package require -preserve Oratcl tmh added on 2004-05-30 21:42:19: Logged In: YES user_id=92123 I have found some additional information from oracle.. --------------- symptom: Dynamically unloading shared library fails symptom: SIGSEGV 11* segmentation violation symptom: Core dump is generated cause: A program, either Pro*C or OCI, that dynamically loads and unloads a shared library that includes libclntsh.so will cause a core dump on exit after dynamically unloading the shared library. This will only occur if a connect and disconnect to Oracle is performed. This documented in <bug:2012268>:CORE DUMP ON EXIT OF PRO*C PROGRAM USING DLCLOSE(). The dlopen loads the users shared object, and this in turn causes libclntsh.so to be loaded into the program. The Oracle trace code in the client registers an exit handler by calling "atexit()". This registers a function which resides inside libclntsh.so to be called at exit from the process. dlclose() unloads the users library and libclntsh.so. exit() tries to call "epc_exit_handler" which is now unmapped. ------- Since Tcl 8.5 now calls dlclose for packages where 8.4 apparently does not. Would it be too late for a feature that allows package writers the option to skip the dlclose ? Also, Oracle provides a solution (hack) to get around the core dump. This is apparently a Solaris only issue. Workaround (Solaris specific): Before starting the process which performs dlopen/dlclose of a module linked with Oracle set the environment variable LD_PRELOAD to point to the libclntsh.so file that is being used. For example: setenv LD_PRELOAD $ORACLE_HOME/rdbms/lib/libclntsh.so.8.0 This maps libclntsh permanently and avoids the core dump. This variable must only be set for programs that encounter the core dump and not set generally. Since this is clearly Oracle's fault, Would someone kindly change the close the status of this bug report. Thanks Todd tmh added on 2004-05-26 11:01:44: Logged In: YES user_id=92123 I have attached a file showing my gdb session and the results. tmh added on 2004-05-26 10:50:29: File Added - 88445: typescript mistachkin added on 2004-05-26 08:06:00: Logged In: YES user_id=113501 What line in the Tcl core actually causes the segfault (especially, is it inside of Tcl_Finalize)? Is your exit handler actually being called (when it's not commented out, that is)? Do you have a stack trace? tmh added on 2004-05-26 04:55:22: Logged In: YES user_id=92123 in the init area. Tcl_CreateExitHandler ((Tcl_ExitProc *) Oratcl_Exit, (ClientData) OratclStatePtr); void Oratcl_Exit (clientData) ClientData clientData; { Oratcl_Clean(clientData); Tcl_DecrRefCount(OMV_null); Tcl_DecrRefCount(OMV_zero); } /* callback - clean up procs left open on interpreter deletetion */ Tcl_CallWhenDeleted(interp, (Tcl_InterpDeleteProc *) Oratcl_Delete, (ClientData) OratclStatePtr); More to the point. If I comment out all exit handling from the Oratcl code. (It's just memory leaks after all :) I still get the seg fault on exit. Todd Also there is a interp delete callback for slave interps. mistachkin added on 2004-05-26 04:38:48: Logged In: YES user_id=113501 Are you simply exiting tclsh or is your application calling one of the Tcl C API functions, if so, which one? As long as Tcl_SetExitProc is never called with a non-NULL pointer, the new exit handling from TIP #121 should not have any effect. Is Tcl_Finalize actually being called? If it is, then Tcl is using the default exit handling and the bug may be in Tcl_Finalize itself. |