[comp.os.os2] Multiscope

peter.fitzsimmons@f628.n250.z1.fidonet.org (peter fitzsimmons) (11/27/89)

* Original: FROM.... Peter Fitzsimmons
* Original: TO...... All
* Forwarded by...... Magnus-CBCS v0.05d at 1:250/628.0

#if 0
I've just spent the last several hours trying to figure out why MED,
(the MultiScope execution monitor that is used with the post mordem
debugger), was NOT doing anything when my program had a stack
overflow.  I finally diagnosed the problem: not all stack overflows
are a result of calling _chkstk(), as Logitech assumes. alloca() and
write() and other functions do their own stack checking.

I discovered this because the bbs I'm working on, Magnus/2,  has
been kicking people off all day with stack overflows, but there
were no PMDs.  MED will not trap divide by zero errors either.

While figuring out how to correct this, I found a bug in the MSC
5.10 runtime too! <all this, and I haven't even started debugging my
OWN code yet!>.  When the divide by zero exception handler is
called, MSC assumes the stack is in a different state that it
actually is. The result of this is that when the program exits, the
errorlevel is NOT 255. It is the lower 8 bits of the offset of the
address that caused the divide by zero interrupt.

The following code shows how to kick MED for both the divide by zero
and stack overflow problems.  The routines StackOvl() and ZeroDiv()
cause a general protection violation on purpose.  If you trace back
in the call chain, you will find the function that really caused the
error.
#endif

#include <stdio.h>
#define INCL_NOPM
#define INCL_DOS
#include <os2.h>

extern void far pascal InitializeMED(void); /* for MultiScope postmortem debugger */
void main(int argc,char * *argv);
int pascal far ZeroDiv(void );
void near StackOvl(int err);
int fubar1(void );
int fubar2(void );


void main(int argc, char **argv)
{
    PFN oldvect;
    extern void ( near * _aexit_rtn)(int errorlevel);


    InitializeMED();
    DosSetVec(VECTOR_DIVIDE_BY_ZERO, ZeroDiv, &oldvect);
    _aexit_rtn = StackOvl;

    if(argc==1)
        fubar1();
    else
        fubar2();
}

int pascal far ZeroDiv(void)
{
    char far *null = 0L;
    *null = 0;                  /* cuase GP fault */
    return(0);
}

void near StackOvl(int err)
{
    int far *null = 0L;
    *null = err;                /* cuase GP fault */
}


int zero = 0;

fubar1()     // cause divide by zero
{
    return zero = 100 / zero;
}

#pragma check_stack(off)

fubar2()    // cuase stack overflow inside CRT
{
    char crap[100];      /* use some stack space */
    static int num = 0;
    printf("hello %d\n", num++, crap);
    return fubar2();
}



--- Magnus-CBCS v0.05d
 * Origin: RT Lab (1:250/628.0)