A turn of events: I have found the cause of the Bus Error in 3.4.x
I will walk all of you through this, so you know now what to do when encountering bugs like these:
Code:
Select all
mech003 /usr/people/everdij/xcircuit/xcircuit-3.4.3> /usr/nekoware/bin/wish8.4 lib/tcl/xcircuit.tcl
Starting xcircuit under Tcl interpreter
Bus error (core dumped)
...upon clicking of the canvas. Since we have a core we can run dbx:
Code:
Select all
mech003 /usr/people/everdij/xcircuit/xcircuit-3.4.3> dbx /usr/nekoware/bin/wish8.4
dbx version 7.3.4 (86441_Nov11 MR) Nov 11 2002 11:31:55
Core from signal SIGBUS: Bus error
(dbx) where
Thread 0x10000
> 0 makepress(clientdata = 0x1000000) ["/usr/people/everdij/xcircuit/xcircuit-3.4.3/events.c":1140, 0x4203d4]
1 <Unknown>() [< unknown >, 0x1932db0]
(dbx)
Two things:
1) Since Tcl/TK looks to be multithreading, which makes sense for a graphical toolkit, the trick is to not debug the xcircexec or any other program, but the tcl shell itself, in this case wish8.4
2) xcircuit events.c line 1140 looks to be suspect. In order to verify this i attempted to run the xcircuit tcl program from the debugger:
Code:
Select all
(dbx) run lib/tcl/xcircuit.tcl
PC value from core file (0x0) is not part of the program.
Assuming return register value (0x0) usable to locate PC.
Process 58056 (wish8.4) started
Starting xcircuit under Tcl interpreter
Process 58056 Thread 0x10000 (wish8.4) stopped on signal SIGBUS: Bus error (default) at [keyhandler:1994 +0x4,0x423c94]
1994 if ((pressmode != 0) && (keywstate == pressmode)) {
(dbx) where
Thread 0x10000
> 0 keyhandler(w = (nil), clientdata = (nil), event = 0x7fff2510) ["/usr/people/everdij/xcircuit/xcircuit-3.4.3/events.c":1994, 0x423c94]
1 xctcl_standardaction(clientData = 0x100145e0, interp = 0x10011be0, objc = 4, objv = 0x7fff2620) ["/usr/people/everdij/xcircuit/xcircuit-3.4.3/tclxcircuit.c":6721, 0x4a75bc]
2 <Unknown>() [< unknown >, 0x19174e0]
(dbx)
Another Bus Error, this time at line 1994 in events.c. BTW, i pressed 'l' to load the library when this Bus Error happened.
So what are those lines and routines in events.c?
Code:
Select all
1129 #ifdef TCL_WRAPPER
1130 xcTimeOutProc makepress(caddr_t clientdata)
1131 #else
1132 xcTimeOutProc makepress(caddr_t clientdata, xcIntervalId *id)
1133 #endif
1134 {
1135 int keywstate = (int)clientdata;
1136
1137 /* Button/Key was pressed long enough to make a "press", not a "tap" */
1138
1139 areastruct.time_id = 0;
1140 pressmode = keywstate; <-----
1141 eventdispatch(keywstate | HOLD_MASK, areastruct.save.x, areastruct.save.y);
1142}
Code:
Select all
1987 if (areastruct.time_id != 0) {
1988 xcRemoveTimeOut(areastruct.time_id);
1989 areastruct.time_id = 0;
1990 keywstate = getkeysignature(event);
1991 }
1992 else {
1993 keywstate = getkeysignature(event);
1994 if ((pressmode != 0) && (keywstate == pressmode)) { <-----
1995 /* Events that require hold & drag (namely, MOVE_MODE) */
1996 /* must be resolved here. Call finish_op() to ensure */
1997 /* that we restore xcircuit to a state of sanity. */
Both involve a comparison/equation of pressmode and keywstate. keywstate is an int but pressmode is not defined in the function, so it must be globally defined at the top of events.c:
Oh it's declared external, so are there other declarations for pressmode? :
Code:
Select all
mech003 /usr/people/everdij/xcircuit/xcircuit-3.4.3> grep pressmode *
events.c:extern int pressmode;
events.c: pressmode = keywstate;
events.c: if ((pressmode != 0) && (keywstate == pressmode)) {
events.c: pressmode = 0;
keybindings.c:extern Boolean pressmode;
keybindings.c: if (pressmode) {
tclxcircuit.c:extern Boolean pressmode;
tclxcircuit.c: pressmode = True;
tclxcircuit.c: pressmode = False; /* Done using this to track 2-button bindings */
xcircuit.c:Boolean pressmode; /* Whether we are in a press & hold state */
xcircuit.c: pressmode = FALSE; /* not in a button press & hold mode yet */
xcircuit.c: pressmode = True; /* 2-button mouse indicator */
xcircuit.c: pressmode = False; /* Done using this to mark 2-button mouse mode */
... WhiskeyTangoFoxtrot, They mixed int with Boolean declaration for pressmode? ... No wonder IRIX SIGBUS'ses when it encounters this.
But what should be the correct type? Int or Boolean? A grep of pressmode in xcircuit 3.8.78 shows this:
Code:
Select all
mech003 /usr/people/everdij/xcircuit/xcircuit-3.8.78> grep pressmode *
events.c:extern int pressmode;
events.c: pressmode = keywstate;
events.c: if ((pressmode != 0) && (keywstate == pressmode)) {
events.c: pressmode = 0;
keybindings.c:extern int pressmode;
keybindings.c: if (pressmode == 1) {
tclxcircuit.c:extern int pressmode;
tclxcircuit.c: pressmode = 1;
tclxcircuit.c: pressmode = 1;
tclxcircuit.c: pressmode = 0; /* Done using this to track 2-button bindings */
xcircuit.c:int pressmode; /* Whether we are in a press & hold state */
xcircuit.c: pressmode = 0; /* not in a button press & hold mode yet */
xtgui.c:extern int pressmode; /* Whether we are in a press & hold state */
xtgui.c: pressmode = 1; /* 2-button mouse indicator */
xtgui.c: pressmode = 0; /* Done using this to mark 2-button mouse mode */
So it must be an int. As a quick test i tried to declare pressmode as Boolean for fun and indeed, no more Bus Errors. The program kinda works but i don't see any lines or libraries. I do see a grid though...
So fixing this makes the Bus Error disappear. I haven't done that for this particular version, because you might want to patch a higher code version of xcircuit where the grid disappears.