Subject: | Crash when built with stubs on macOS |
When Tcl.pm is built on macOS (using included Perl 5.18 + Tcl/Tk 8.5.9) with stubs, Perl crashes immediately with an error like this one:
Signal SEGV at /System/Library/Perl/5.18/darwin-thread-multi-2level/DynaLoader.pm line 105.
DynaLoader::bootstrap_inherit('Tcl', 1.27) called at ../tcl.pm/blib/lib/Tcl.pm line 465
require Tcl.pm called at -e line 0
main::BEGIN() called at ../tcl.pm/blib/lib/Tcl.pm line 0
eval {...} called at ../tcl.pm/blib/lib/Tcl.pm line 0
The cause is a (NULL + 4) pointer dereference. Building Tcl.pm without stubs defines USE_TCL_STUBS, which on Mac in turn defines TCL_LIB_FILE to "Tcl". In NpLoadLibrary() (Tcl.xs line 286):
…
if (!handle) {
sprintf(buffer,"%sfailed dlopen(%s,...);\n", buffer, libname);
/* Try based on anywhere in the path. */
strcpy(libname, TCL_LIB_FILE);
handle = dlopen(libname, RTLD_NOW | RTLD_GLOBAL);
}
if (!handle) {
/* Try different versions anywhere in the path. */
sprintf(buffer,"%sfailed dlopen(%s,...);\n", buffer, libname);
char *pos = strstr(libname, "tcl8")+4;
if (*pos == '.') {
pos++;
}
…
TCL_LIB_FILE ("Tcl") gets copied into libname; since libname then does not contain substring "tcl8", strstr() returns NULL. Then *pos is immediately dereferenced, which crashes.
I currently have no proposed fix for this; the NpLoadLibrary() function seems a bit messy, possibly from having accumulated various hacks over the years. Building without stubs seems to work fine.