Tcl Source Code

View Ticket
Login
Ticket UUID: 26f1328a86863216c8fae28f55ff0e09135d5d35
Title: sizeof(int) < sizeof(void*) -> Crash
Type: Bug Version: 8.7a6
Submitter: anonymous Created on: 2022-01-07 16:13:04
Subsystem: 53. Configuration and Build Tools Assigned To: jan.nijtmans
Priority: 5 Medium Severity: Minor
Status: Closed Last Modified: 2022-01-15 13:26:03
Resolution: Fixed Closed By: anonymous
    Closed on: 2022-01-15 13:26:03
Description:
I'm having fun trying to port Tcl to Plan 9 at the moment.

One early problem was that Tcl crashed as soon as I was executing
anything, like "parray env".  Debugging the problem, it turns out that
there is a problem in the bytecode interpreter.  This is quite similar
to #2796438 on AIX, it might be the same issue.

The bytecode interpreter uses the macro TclGetInt1AtPtr to read an
offset from the bytecode.  These offsets can be negative Problem is
that the result of that macro is an unsigned int, despite the name.
Adding a huge unsigned number to a pointer instead of a small negative
signed is of course not healthy unless you can count on wrap-around.
But on Plan9/amd64, sizeof(int) == 4 and sizeof(void*) == 8.

The attached path fixes this.  Sorry that this patch is made against
the Git mirror, I hope that is ok.
User Comments: anonymous added on 2022-01-15 13:26:03:
Thanks, Jan.

jan.nijtmans added on 2022-01-12 14:21:13:

Proposed fix committed [7178b3b4397d5c8c|here]. Looks good, but first let's see what Github ACTIONS thinks of it.

Thanks for the report and the patch!


anonymous (claiming to be [email protected]) added on 2022-01-12 13:07:07:
> result of that macro is an unsigned int, [...]
> But on Plan9/amd64, sizeof(int) == 4 and sizeof(void*) == 8.

Actually, my initial analysis was wrong regarding the reason for this.
The sizeofs are the same on Linux/amd64.  Still the macro returns an
int on Linux, but an unsigned int on Plan 9, and that *is* actually
the underlying problem.

anonymous (claiming to be [email protected]) added on 2022-01-12 13:00:35:
Some more information:

The problem originates in JUMP_PEEPHOLE_F (tclExecute.c:317), where
TclGetInt4AtPtr(pc+1)) is calculated and than added to pc in
NEXT_INST_F (tclExecute.c:246).  The bytes at the incoming pc+1 are
0xFF,0xFF,0xFD,0xBC, which is supposed to mean -580.

The attached test program exercises this.  The result on Linux/amd64
is

    $ gcc -o ts test-signed-tcl.c && ./ts
    12 -> U:0
    12U -> U:1
    -12 -> U:0
    int(bytes): -580 U:0
    ptr: 0x55c79ab8f135 + int(bytes) -> 0x55c79ab8eef1 (diff:-580)

The result on Plan 9 (9front/amd64) is:

    term% pcc -o tsp test-signed-tcl.c && tsp
    12 -> U:0
    12U -> U:1
    -12 -> U:0
    int(bytes): -580 U:1
    ptr: 0x200028 + int(bytes) -> 0x1001FFDE4 (diff:4294966716)

Attachments: