Ticket UUID: | 555058 | |||
Title: | Tcl initialization fails in external app | |||
Type: | Bug | Version: | obsolete: 8.4a4 | |
Submitter: | rfranke | Created on: | 2002-05-12 09:22:58 | |
Subsystem: | 38. Init - Library - Autoload | Assigned To: | andreas_kupries | |
Priority: | 5 Medium | Severity: | ||
Status: | Closed | Last Modified: | 2002-07-09 09:44:53 | |
Resolution: | None | Closed By: | davygrvy | |
Closed on: | 2002-07-09 02:44:53 | |||
Description: |
OS Platform: Windows 2000 / MinGW or Active State Tcl The aim is to load Tcl dynamically into a non-Tcl application, e.g. as Tcl is used as command language in a component, but not in the complete application. This means that Tcl_Main can not be called for the initialization of Tcl. Until version 8.3, one could create a Tcl_Interp and use it locally in the library. However, Tcl 8.4a4 crashes with a segmentation violation when evaluating some built-in commands, e.g. "file" and "source". Please see the little example program attachted to this report, which is working with Tcl 8.0 and Tcl 8.3, but not with Tcl 8.4. How can one use Tcl without Tcl_Main? How is this problem solved in the Tcl Plugin? (this bug report might be related to 540226: encoding init in dynamic loaded Tcl) | |||
User Comments: |
davygrvy added on 2002-07-09 09:44:53:
Logged In: YES user_id=7549 On behalf of Andreas, I'll close this. Yes, Tcl initialization has changed since 8.0, but is documented and I woudn't consider this a bug, just a change in behavior. davygrvy added on 2002-06-03 04:20:21: Logged In: YES user_id=7549 >How can one use Tcl without Tcl_Main? Call Tcl_FindExecutable() to set the library path, thus where the encoding files are prior to the first Tcl_Init(). >How is this problem solved in the Tcl Plugin? Umm, no development work has been done to the plugin for at least 2 years now, AFAIK. It's way out-of-date. Please don't refer to it as a reference point. It's misuse of the event loop and thread contexts are bad enough as it is. Without knowing argv[0], at least on windows, can be derived with: char app[MAX_PATH]; GetModuleFile(GetModuleHandle(NULL), app, MAX_PATH); Tcl_FindExecutable(app); The first "crash" listed in the test source is not a crash. Tcl_Init() returns TCL_ERROR and the result is set with the error message. The second might be be worth digging into, but for how the logic of initialisation is at this moment, today, calling Tcl_FindExecutable() before Tcl_Init() is the correct way to do it. To have Tcl_Init call Tcl_FindExecutable on it's own would require argv[0], or the derivation of it. dgp added on 2002-06-01 07:05:39: Logged In: YES user_id=80530 I can't reproduce the crash on Linux. Assigning to someone more able to do testing on Win2K. Again, the problem is a crash when Tcl_FindExecutable has not been called. Right fix is to add that call, but can we change the crash into an error message? davygrvy added on 2002-05-28 13:45:55: Logged In: YES user_id=7549 Also note that you need to use writable strings for the script arguement to Tcl_Eval(). /* call the command */ if (Tcl_Eval(interp, "MyCmd") != TCL_OK) { During the parsing phase, Tcl can (could need to) write NULLs to the string. rfranke added on 2002-05-15 00:36:05: Logged In: YES user_id=155217 Sorry for having used the wrong Tcl sources for generating the stack trace. Though the trace I have attached should still give a rough idea. And as the problem is already located, i.e. missing call to Tcl_FindExecutable, you might be able to reproduce the error with any version. If you say that the missing call to that function is the most common error when embedding Tcl, couldn't then at least a check be introduced before the crash and the calling function, e.g. Tcl_Init, return an according error? andreas_kupries added on 2002-05-14 01:11:54: Logged In: YES user_id=75003 My apologies ... I forgot to read the other comments before responding to the latest comment about the encoding system not initialized. dgp added on 2002-05-14 01:07:35: Logged In: YES user_id=80530 Yes, we've already established that a Tcl_FindExecutable solves this problem. Even without a Tcl_FindExecutable() call, though, Tcl should not crash. Maybe it will not work properly, but it should not crash. Locating the crash might convert it into a good error message. andreas_kupries added on 2002-05-14 00:07:35: Logged In: YES user_id=75003 Query: Do you use "Tcl_FindExecutable" ? Failure to call this function is the most common error when it comes to embeding newer Tcl's into an application. See also http://wiki.tcl.tk/1315.html or http://wiki.tcl.tk/Tcl_FindExecutable* ( The * is part of the url) vincentdarley added on 2002-05-13 23:54:15: Logged In: YES user_id=32170 Unfortunately, these stack traces appear to be for non-cvs- head of Tcl, so it's not possible to work out what line 1920 of tclWinFCmd.c is. Could you perhaps add some context? The problem is almost certainly caused by the encodings subsystem not being initialised. rfranke added on 2002-05-13 03:11:30: Logged In: YES user_id=155217 You are right, it works with Tcl_FindExecutable; Thanks a lot for this fast help! Here is the MSVC call stack for failed Tcl_Init: 00000000() TclpObjNormalizePath(Tcl_Interp * 0x00000000, Tcl_Obj * 0x007d3c98, int 0) line 1920 + 25 bytes TclNormalizeToUniquePath(Tcl_Interp * 0x00000000, Tcl_Obj * 0x007d3c98) line 980 + 15 bytes FSNormalizeAbsolutePath(Tcl_Interp * 0x00000000, Tcl_Obj * 0x007d3d58) line 902 + 13 bytes Tcl_FSGetNormalizedPath(Tcl_Interp * 0x00000000, Tcl_Obj * 0x007d3d70) line 3982 + 13 bytes Tcl_FSGetFileSystemForPath(Tcl_Obj * 0x007d3d70) line 4497 + 11 bytes Tcl_FSAccess(Tcl_Obj * 0x007d3d70, int 0) line 1551 + 9 bytes CheckAccess(Tcl_Interp * 0x007a5208, Tcl_Obj * 0x007d3d70, int 0) line 1321 + 13 bytes Tcl_FileObjCmd(int * 0x00000000, Tcl_Interp * 0x007a5208, int 3, Tcl_Obj * const * 0x007a5fd0) line 905 + 18 bytes TclEvalObjvInternal(Tcl_Interp * 0x007a5208, int 3, Tcl_Obj * const * 0x007a5fd0, char * 0x00000000, int 0, int 0) line 3030 + 25 bytes TclExecuteByteCode(Tcl_Interp * 0x007a5208, ByteCode * 0x007d44b0) line 1357 + 27 bytes TclCompEvalObj(Tcl_Interp * 0x007a5208, Tcl_Obj * 0x007a5598, int 0) line 941 + 13 bytes Tcl_EvalObjEx(Tcl_Interp * 0x007a5208, Tcl_Obj * 0x007a5598, int 0) line 3865 + 15 bytes TclObjInterpProc(int * 0x007d2f20, Tcl_Interp * 0x007a5208, int 1, Tcl_Obj * const * 0x0012fee4) line 1074 + 21 bytes TclEvalObjvInternal(Tcl_Interp * 0x007a5208, int 1, Tcl_Obj * const * 0x0012fee4, char * 0x100b10d2, int 7, int 0) line 3030 + 25 bytes Tcl_EvalEx(Tcl_Interp * 0x007a5208, char * 0x100b0d1c initScript, int 957, int 0) line 3577 + 30 bytes Tcl_Eval(Tcl_Interp * 0x007a5208, char * 0x100b0d1c initScript) line 3733 + 17 bytes Tcl_Init(Tcl_Interp * 0x007a5208) line 768 + 14 bytes main(int 1, char * * 0x007c14b0) line 21 + 10 bytes TCLINOTHERAPP! mainCRTStartup + 180 bytes KERNEL32! 77e892a6() When not calling Tcl_Init, then this results from Tcl_Eval(interp, "source ...") 00000000() TclpObjNormalizePath(Tcl_Interp * 0x00000000, Tcl_Obj * 0x007a5568, int 0) line 1920 + 25 bytes TclNormalizeToUniquePath(Tcl_Interp * 0x00000000, Tcl_Obj * 0x007a5568) line 980 + 15 bytes FSNormalizeAbsolutePath(Tcl_Interp * 0x00000000, Tcl_Obj * 0x007a5610) line 902 + 13 bytes Tcl_FSGetCwd(Tcl_Interp * 0x00000000) line 1862 + 13 bytes Tcl_FSGetNormalizedPath(Tcl_Interp * 0x00000000, Tcl_Obj * 0x007a5658) line 3969 + 9 bytes Tcl_FSGetFileSystemForPath(Tcl_Obj * 0x007a5658) line 4497 + 11 bytes Tcl_FSStat(Tcl_Obj * 0x007a5658, _stati64 * 0x0012fc88) line 1448 + 9 bytes Tcl_FSEvalFile(Tcl_Interp * 0x007a5208, Tcl_Obj * 0x007a5658) line 1228 + 13 bytes Tcl_SourceObjCmd(int * 0x00000000, Tcl_Interp * 0x007a5208, int 2, Tcl_Obj * const * 0x0012fef4) line 976 + 16 bytes TclEvalObjvInternal(Tcl_Interp * 0x007a5208, int 2, Tcl_Obj * const * 0x0012fef4, char * 0x0040aa8c, int 20, int 0) line 3030 + 25 bytes Tcl_EvalEx(Tcl_Interp * 0x007a5208, char * 0x0040aa8c, int 20, int 0) line 3577 + 30 bytes Tcl_Eval(Tcl_Interp * 0x007a5208, char * 0x0040aa8c) line 3733 + 17 bytes main(int 1, char * * 0x007c14b0) line 40 + 15 bytes TCLINOTHERAPP! mainCRTStartup + 180 bytes KERNEL32! 77e892a6() dgp added on 2002-05-12 23:26:04: Logged In: YES user_id=80530 Can you provide stack traces for the crashes you see? That will help locate the problem. I notice that your code is missing a call to Tcl_FindExecutable() first thing in the main(). Adding that may correct the symptoms, but we should stil locate and prevent crashes. rfranke added on 2002-05-12 16:22:58: File Added - 22937: TclInOtherApp.c |
Attachments:
- TclInOtherApp.c [download] added by rfranke on 2002-05-12 16:22:58. [details]