Ejemplo n.º 1
0
/* Handle profiler marks (hardcoded breakpoints with a string) */
static bool ProcessMark( pid_t pid, user_regs_struct *regs )
{
    if( (regs->edx & 0xffff) != 0 ) {   /* this is a mark */
        char            buff[BUFF_SIZE];
        int             len = 0;
        seg_offset      where;

        /* read the mark string char by char */
        for( ;; ) {
            if( len >= (BUFF_SIZE - 1) )
                break;
            ReadMem( pid, buff + len, regs->eax + len, 1 );
            if( buff[len] == '\0' )
                break;
            ++len;
        }
        buff[len] = '\0';
        where.segment = FlatSeg;
        where.offset = regs->eip;
        WriteMark( buff, where );
        return( true );
    } else {
        dbg_printf( "hardcoded breakpoint was not a mark!\n" );
        return( false );
    }
}
Ejemplo n.º 2
0
/*
 * StartProg - start sampling a program
 */
void StartProg( char *cmd, char *prog, char *full_args, char *dos_args )
{
    DWORD       code;
    DWORD       tid;
    CONTEXT     con;
    BOOL        waiting_for_first_bp;
    SIZE_T      len;
    DWORD       continue_how;
    BOOL        rc;
    seg_offset  where;
    DWORD       ttid;
    HANDLE      tth;

    cmd = cmd;

    strcpy( utilBuff, prog );
    strcat( utilBuff, " " );
    strcat( utilBuff, full_args );

    loadProg( prog, utilBuff );
    tid = debugEvent.dwThreadId;

    tth = CreateThread( NULL, 1024, TimerThread, NULL, 0, &ttid );
    if( !tth ) {
        internalError( MsgArray[MSG_SAMPLE_3 - ERR_FIRST_MESSAGE] );
    }
    /* attempt to ensure that we can get all of our samples in one shot */
    SetThreadPriority( tth, THREAD_PRIORITY_TIME_CRITICAL );

    Output( MsgArray[MSG_SAMPLE_1 - ERR_FIRST_MESSAGE] );
    Output( prog );
    Output( "\r\n" );

    waiting_for_first_bp = TRUE;
    continue_how = DBG_CONTINUE;

    for( ;; ) {
        ContinueDebugEvent( taskPid, tid, continue_how );
        rc = WaitForDebugEvent( &debugEvent, INFINITE );
        continue_how = DBG_CONTINUE;
        tid = debugEvent.dwThreadId;
        switch( debugEvent.dwDebugEventCode ) {
        case EXCEPTION_DEBUG_EVENT:
            code = debugEvent.u.Exception.ExceptionRecord.ExceptionCode;
            switch( code ) {
            case STATUS_SINGLE_STEP:
                if( timeOut ) {
                    myGetThreadContext( tid, &con );
                    RecordSample( con.Eip, con.SegCs, tid );
                    timeOut = FALSE;
                }
                break;
            case STATUS_BREAKPOINT:
                if( !waiting_for_first_bp ) {
                    myGetThreadContext( tid, &con );
                    con.Eip--;
                    if( (con.Edx & 0xffff) != 0 ) {    /* this is a mark */
                        ReadProcessMemory( processHandle, (LPVOID)con.Eax, utilBuff, BUFF_SIZE - 1, len );
                        utilBuff[len] = '\0';
                        where.segment = con.SegCs;
                        where.offset = con.Eip;
                        WriteMark( utilBuff, where );
                    } else {            /* this passes CommonAddr */
                        commonAddr.segment = con.Ecx & 0xffff;
                        commonAddr.offset = con.Ebx;
                    }
                } else {
                    waiting_for_first_bp = FALSE;
                }
                break;
            case STATUS_DATATYPE_MISALIGNMENT:
            case STATUS_ACCESS_VIOLATION:
            case STATUS_IN_PAGE_ERROR:
            case STATUS_NO_MEMORY:
            case STATUS_ILLEGAL_INSTRUCTION:
            case STATUS_NONCONTINUABLE_EXCEPTION:
            case STATUS_INVALID_DISPOSITION:
            case STATUS_ARRAY_BOUNDS_EXCEEDED:
            case STATUS_FLOAT_DENORMAL_OPERAND:
            case STATUS_FLOAT_DIVIDE_BY_ZERO:
            case STATUS_FLOAT_INVALID_OPERATION:
            case STATUS_FLOAT_OVERFLOW:
            case STATUS_FLOAT_STACK_CHECK:
            case STATUS_FLOAT_UNDERFLOW:
            case STATUS_INTEGER_DIVIDE_BY_ZERO:
            case STATUS_INTEGER_OVERFLOW:
            case STATUS_PRIVILEGED_INSTRUCTION:
            case STATUS_STACK_OVERFLOW:
            case STATUS_CONTROL_C_EXIT:
                if( debugEvent.u.Exception.dwFirstChance ) {
                    continue_how = DBG_EXCEPTION_NOT_HANDLED;
                } else {
                    Output( MsgArray[MSG_SAMPLE_4 - ERR_FIRST_MESSAGE] );
                    Output( "\r\n" );
                    doneSample = TRUE;
                    TerminateProcess( processHandle, 0 );
                    report();
                    return;
                }
                break;
            default:
                continue_how = DBG_EXCEPTION_NOT_HANDLED;
                break;
            }
            break;
        case LOAD_DLL_DEBUG_EVENT:
            if( GetDllName( &debugEvent.u.LoadDll, utilBuff, sizeof( utilBuff ) ) ) {
                codeLoad( debugEvent.u.LoadDll.hFile,
                            (DWORD) debugEvent.u.LoadDll.lpBaseOfDll,
                            utilBuff,
                            SAMP_CODE_LOAD );
            }
            break;
        case CREATE_THREAD_DEBUG_EVENT:
            newThread( debugEvent.dwThreadId, debugEvent.u.CreateThread.hThread );
            break;
        case EXIT_THREAD_DEBUG_EVENT:
            deadThread( debugEvent.dwThreadId );
            break;
        case EXIT_PROCESS_DEBUG_EVENT:
            doneSample = TRUE;
//          TerminateProcess( processHandle, 0 ); - already gone!!
            report();
            return;
        }
    }

} /* StartProg */
Ejemplo n.º 3
0
void StartProg( const char *cmd, const char *prog, char *full_args, char *dos_args )
{

    const char  *src;
    char        *dst;
    USHORT      drive;
    ULONG       map;
    USHORT      len;
    USHORT      tid;
    USHORT      rc;
    char        buff[BSIZE];
    seg_offset  where;
    char        *cmd_tail;

    /* unused parameters */ (void)cmd;

    MaxThread = 0;
    GrowArrays( 1 );
    src = prog;
    dst = UtilBuff;
    DosQCurDisk( &drive, &map );
    if( src[0] == '\0' || src[1] == '\0' || src[1] != ':' ) {
        *dst++ = drive - 1 + 'A';
        *dst++ = ':';
    } else {
        *dst++ = *src++;
        *dst++ = *src++;
    }
    if( src[0] != '\\' ) {
        ++dst;
        len = BUFF_SIZE - ( dst - UtilBuff );
        DosQCurDir( drive, (PBYTE)dst, &len );
        dst[-1] = '\\';
        if( *dst == '\\' || *dst == '\0' ) {
            *dst = '\0';
        } else {
            while( *dst != '\0' ) {
                ++dst;
            }
            *dst++ = '\\';
        }
    }
    strcpy( dst, src );
    dst = UtilBuff + strlen( UtilBuff ) + 1;
    cmd_tail = dst;
    strcpy( dst, full_args );
    dst += strlen( dst );
    *++dst = '\0';      /* Need two nulls at end */
    LoadProg( UtilBuff, cmd_tail );
    Output( MsgArray[MSG_SAMPLE_1 - ERR_FIRST_MESSAGE] );
    Output( UtilBuff );
    Output( "\r\n" );
    Buff.pid = Pid;
    Buff.tid = 1;
    Buff.cmd = PT_CMD_STOP;
    LibLoadPTrace( &Buff );
    if( OSVer < 0x1400 ) {
        /* OS/2 2.x already dumped out MainMod as a Module load */
        CodeLoad( &Buff, MainMod, ExeName, SAMP_MAIN_LOAD );
    }
    InitialCS = Buff.u.r.CS;
    rc = DosCreateThread( Sleeper, (PUSHORT)&tid, Stack + STACK_SIZE );
    if( rc != 0 ) {
        InternalError( MsgArray[MSG_SAMPLE_4 - ERR_FIRST_MESSAGE] );
    }
    rc = DosSetPrty( PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, tid );
    if( rc != 0 ) {
        InternalError( MsgArray[MSG_SAMPLE_5 - ERR_FIRST_MESSAGE] );
    }
    Buff.pid = Pid;
    Buff.tid = 1;
    for( ;; ) {
        Buff.cmd = PT_CMD_GO;
        if( LibLoadPTrace( &Buff ) != 0 ) {
            InternalError( MsgArray[MSG_SAMPLE_7 - ERR_FIRST_MESSAGE] );
        }
        if( Buff.cmd == PT_RET_BREAK && Buff.u.r.DX != 0 ) {    /* a mark */
            len = 0;
            Buff.segv = Buff.u.r.DX;
            Buff.offv = Buff.u.r.AX;
            for( ;; ) {
                Buff.cmd = PT_CMD_READ_MEM_D;
                DosPTrace( &Buff );
                buff[len] = Buff.value;
                if( Buff.cmd != PT_RET_SUCCESS )
                    buff[len] = '\0';
                if( len == BSIZE )
                    buff[len] = '\0';
                if( buff[len] == '\0' )
                    break;
                ++len;
                Buff.offv++;
            }
            where.segment = Buff.u.r.CS;
            where.offset = Buff.u.r.IP;
            WriteMark( buff, where );
            Buff.cmd = PT_CMD_READ_REGS;
            DosPTrace( &Buff );
            Buff.u.r.IP++;
            Buff.cmd = PT_CMD_WRITE_REGS;
            DosPTrace( &Buff );
            continue;
        } else if( Buff.cmd == PT_RET_BREAK ) {         /* common info pass */
            CommonAddr.segment = Buff.u.r.CX;
            CommonAddr.offset = Buff.u.r.BX;
            Buff.cmd = PT_CMD_READ_REGS;
            DosPTrace( &Buff );
            Buff.u.r.IP++;
            Buff.cmd = PT_CMD_WRITE_REGS;
            DosPTrace( &Buff );
            continue;
        }
        if( Buff.cmd == PT_RET_FUNERAL )
            break;
        if( Buff.cmd != PT_RET_LIB_LOADED
          && Buff.cmd != PT_RET_STOPPED
          && Buff.cmd != PT_RET_TRD_TERMINATE ) {
            InternalError( MsgArray[MSG_SAMPLE_6 - ERR_FIRST_MESSAGE] );
            break;
        }
        RecordSample( Buff.u.r.IP, Buff.u.r.CS, Buff.tid );
    }
    report();
}
Ejemplo n.º 4
0
void StartProg( char *cmd, char *prog, char *full_args, char *dos_args )
{

    seg_offset  where;
    int         error_num;
    char        buff[BSIZE];
    Fptr32      fp;
    short       initial_cs;
    int         len;

    cmd = cmd;
    SampleIndex = 0;
    CurrTick  = 0L;

    D32HookTimer( TimerMult );  /* ask for timer - before D32DebugInit!! */
    D32DebugBreakOp(&Break);    /* Get the 1 byte break op */

    error_num = D32DebugInit( &Proc );
    if( error_num == 0 ) {
        strcpy( buff, full_args );
        error_num = D32DebugLoad( prog, buff, &Proc );
    }
    if( error_num != 0 ) {
        Output( MsgArray[MSG_SAMPLE_2-ERR_FIRST_MESSAGE] );
        Output( prog );
        Output( "\r\n" );
        MsgFini();
        exit(1);
    }

    where.offset = 0;
    where.segment = 0;
    WriteCodeLoad( where, ExeName, SAMP_MAIN_LOAD );

    fp.sel = 1;
    fp.off = 0;
    D32Relocate(&fp);
    WriteAddrMap( 1, fp.sel, fp.off );

    initial_cs = Proc.cs;
    for( ;; ) {
        D32DebugRun( &Proc );
        if( SampleIndex > Margin && Proc.cs == initial_cs ) {
            StopAndSave();
        }
        if( Proc.int_id == 8 ) {
            ++InsiderTime;
            RecordSample( Proc.eip, Proc.cs );
            --InsiderTime;
        } else if( Proc.int_id == 3 && (Proc.edx & 0xffff) != 0 ) {
            len = 0;                                    /* this is a mark */
            where.segment = Proc.edx & 0xffff;
            where.offset = Proc.eax;
            for( ;; ) {
                if( !D32AddressCheck( where.segment, where.offset, 1, NULL ) ) break;
                D32DebugRead( where.offset, where.segment, 0, &buff[len], 1 );
                if( len == BSIZE ) break;
                if( buff[len] == '\0' ) break;
                len++;
                where.offset++;
            }
            buff[len] = '\0';
            where.segment = Proc.cs;
            where.offset = Proc.eip;
            WriteMark( buff, where );
            Proc.eip++;
        } else if( Proc.int_id == 3 ) {         /* remember common storage */
            CommonAddr.segment = Proc.ecx & 0xffff;            /* area ... */
            CommonAddr.offset = Proc.ebx;
            Proc.eip++;
        } else {
            break;
        }
    }
    D32UnHookTimer();
    if( Proc.int_id != 0x21 ) {
        Output( MsgArray[MSG_SAMPLE_1-ERR_FIRST_MESSAGE] );
        Output( MsgArray[Exceptions[Proc.int_id]+MSG_EXCEPT_0-ERR_FIRST_MESSAGE] );
        Output( "\r\n" );
    }
    D32DebugTerm();
    report();
}