A.Sloman wrote:
> vars b = newarray([-1 5 -1 5]);
> b(6) =>
>
> ;;; MISHAP - INVALID ARRAY SUBSCRIPT
> ;;; INVOLVING: 6
> ;;; DOING : sys_exception_final sys_exception_handler
> ;;; Segmentation fault (core dumped)
My redHat 6.2 on slow 486 only writes the first 2 lines if the mishap.
> It looks as if the error test works, then _array_sub calls the routine
> array_sub_error which succeeds in calling Sub_error, which invokes
> pop11's generic error handler, which starts printing out the error
> message, and fails half way through printing.
I think:
when there are no subscript errors, _array_sub exits via the
jmp *_PD_EXECUTE(%eax)
ELSE it gets to:
subl $4, %USP ;;; reveal the last index again
call XC_LAB(weakref Sys$-Array$-Sub_error)
call XC_LAB(setpop) ;;; in case the error returns
and crashes ?!
> I suspect something is wrong with the machine instructions in both files
> and I wonder if someone familiar with the PC architecture can tell what
> is wrong either from the linux version or the windows version. They are
> accessible here if you don't have local versions:
Well It's been years since I needed to punish my self with asm, but:
rc/*.s is not 'standard' intel syntax, so heurisstics are needed.
But I haven't found out the meaning of 'slodl' in:
slodl
testl %eax, %eax
Q1. Did I compile the linux V15.53 that I downloaded ?
If so I could make a spare version and patch and test it.
It's near impossible to debug without making patchs and traces.
> Printing out the calling stack (the DOING list) is done by
> sys_pr_message(count, message, idstring, severity);
> defined in $popsrc/errors.p
!! OK, 'help sys_pr_message' explains this. I'll look later.
> ........
> In this case I don't know if the problem is heap corruption, or
> corruption of the pop11 control stack, or something else.
A simple rule is that each 'call' must be matched by it's (closing bracket)
'ret'. When I look at many of the *.s in my ..../src/ they are all 'well
structured', in that the 'exit' is via a 'ret'. {using mc under linux
is very usefull to find and inspect the sources.}
Analysing the structure of DEF_C_LAB (_array_sub)
we see that it can either exit via
jmp *_PD_EXECUTE(%eax)
if the arguments are OK
or fall through
array_sub_error:
subl $4, %USP ;;; reveal the last index again
call XC_LAB(weakref Sys$-Array$-Sub_error)
call XC_LAB(setpop) ;;; in case the error returns
if the arguments are not OK.
{ Here's a hi-level version:
L1.8: ;;; Start of loop: analysis
.....
IF %USP = 2
THEN goto array_sub_error
.....
IF %eax Relation %edx
THEN goto array_sub_error
.....
IF %eax Relation2 %eax
THEN goto L1.9 {i.e. skip imull }
imull %eax, %edx
L1.9: .....
IF %eax ~Relation2 %eax
THEN goto L1.8
L1.10: <-- skip to here if "zero already for a 0-dimensional array"
.....
jmp *_PD_EXECUTE(%eax) _-> exit if args OK
array_sub_error:
call XC_LAB(weakref Sys$-Array$-Sub_error)
call XC_LAB(setpop) ;;; in case the error returns
! Crash if return here !? }
When I examine the various calls to XC_LAB in src/*.s (using mc),
I see that some are commented "never returns".
{Sometimes XC_LAB is reached by a jump. }
In the case that the code is not 'well structured'; to return to the
instruction after the call, it still must 'pop the stack appropriately'
even it uses some address other than the 'pushed return address',
to continue.
That's where I would focus.
Ie. is XC_LAB(<arg>) 'smarty pants code' which can continue/exit
without a ret instruction ? If not it must crash.
I don't see where the XC_LAB(<arg>) code is !?
What is: src/syscomp/do_asm.p about ?
-- Chris Glur.
|