rtdbgst.cpp
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C++ 代码 · 共 866 行 · 第 1/2 页
CPP
866 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#ifndef NDEBUG
#undef __OBSCURE_STREAM_INTERNALS // kludge! we need manipulate with FILE structure
#include "cpplib.h"
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include "rtexcept.h"
#include "exc_pr.h"
extern "C" _WCRTLINK extern FILE *__get_std_stream( unsigned handle );
#define MX_FSTK 10
#define default_file "_CPPDBG_."
#define STDOUT_FILENO 1
static FILE* fstk[ MX_FSTK ]; // suspended files
static unsigned index; // top of files stack
static int logging; // true ==> logging at level 0
static void dumpDtorCmd( RW_DTREG*, DTOR_CMD* );
enum FT // types of formatting
{ FT_RW // - R/W header
, FT_RO // - R/O header
, FT_STATE // - state table
, FT_FLAGS // - flags
, FT_BYTE // - byte
, FT_TEXT // - text
, FT_PTR // - data ptr
, FT_RTN // - code ptr
, FT_OFF // - offset
, FT_DTOFF // - (dtor,offset) list
, FT_DTADDR // - (dtor,addr) list
, FT_TSIG // - type signature
, FT_TSIGS // - type signature list
, FT_INDENT // - new line, indent
, FT_CONT // - continue
, FT_END // - end
};
static void dumpTitle( // DUMP A TITLE
const char* title ) // - the title
{
printf( "%s\n\n", title );
}
static unsigned indent = 1; // # of indentations
static void dump( // FORMATTED DUMP
enum FT ft, ... ) // - FT formatting
{
va_list args; // - for variable arguments
rboolean done; // - TRUE ==> done formatting
size_t blk_type; // - type of block
RW_DTREG* rw; // - R/W header
va_start( args, ft );
for( done = FALSE; ! done; ft = va_arg( args, enum FT ) ) {
switch( ft ) {
case FT_RW :
{ const char* text; // - text
text = va_arg( args, char* );
rw = va_arg( args, RW_DTREG* );
blk_type = rw->base.ro->base.reg_type;
dump( FT_TEXT, "\nBLK-RW:"
, FT_PTR, text, rw
#ifdef RW_REGISTRATION
, FT_PTR, "prev", rw->base.prev
#endif
, FT_PTR, "ro", rw->base.ro
, FT_OFF, "state_var", rw->base.state_var
, FT_CONT );
} break;
case FT_RO :
{ const char* text; // - text
RO_DTREG* ro; // - R/O header
text = va_arg( args, char* );
ro = va_arg( args, RO_DTREG* );
dump( FT_TEXT, "\nBLK-RO:"
, FT_OFF, "type", ro->base.reg_type
, FT_CONT );
} break;
case FT_FLAGS :
{ const char* text; // - text
uint_8 *ptr; // - pointer to flags
unsigned count; // - offset
unsigned bits; // - # bits left in byte
uint_8 byte; // - contains flags (being shifted)
text = va_arg( args, char* );
count = va_arg( args, unsigned );
ptr = va_arg( args, uint_8* );
printf( " %s=", text );
for( bits = 0; count > 0; --count, --bits, byte >>= 1 ) {
if( bits == 0 ) {
byte = *ptr++;
bits = 8;
}
printf( byte & 1 ? "1" : "0" );
}
} break;
case FT_BYTE :
{ const char* text; // - text
uint_8 byte; // - byte
text = va_arg( args, char* );
byte = va_arg( args, uint_8 );
printf( " %s=%x", text, byte );
} break;
case FT_TEXT :
{ const char* text; // - text
text = va_arg( args, char* );
printf( " %s", text );
} break;
case FT_PTR :
{ const char* text; // - text
void *ptr; // - pointer to data
text = va_arg( args, char* );
ptr = va_arg( args, void* );
printf( " %s=%x", text, ptr );
} break;
case FT_RTN :
{ const char* text; // - text
pFUNVOIDVOID rtn; // - routine
text = va_arg( args, char* );
rtn = va_arg( args, pFUNVOIDVOID );
printf( " %s=%x", text, rtn );
} break;
case FT_OFF :
{ const char* text; // - text
unsigned offset; // - offset
text = va_arg( args, char* );
offset = va_arg( args, unsigned );
printf( " %s=%x", text, offset );
} break;
case FT_TSIG :
{ RT_TYPE_SIG sig; // - type signature
THROBJ type; // - type of signature
sig = va_arg( args, RT_TYPE_SIG );
if( sig == NULL ) {
type = THROBJ_ANYTHING;
} else {
type = sig->hdr.type;
}
dump( FT_INDENT
, FT_PTR, "type-sig", sig
, FT_BYTE, "type", type
, FT_CONT );
switch( type ) {
case THROBJ_REFERENCE :
sig = CPPLIB( ts_refed )( sig );
dump( FT_PTR, "ref-indirect", sig
, FT_CONT );
break;
case THROBJ_PTR_CLASS :
sig = CPPLIB( ts_pnted )( sig );
dump( FT_PTR, "ptr-class", sig
, FT_CONT );
break;
case THROBJ_PTR_SCALAR :
if( sig->base.indirect ) {
sig = CPPLIB( ts_pnted )( sig );
dump( FT_PTR, "ptr-scalar", sig
, FT_CONT );
}
break;
case THROBJ_CLASS :
case THROBJ_CLASS_VIRT :
case THROBJ_SCALAR :
case THROBJ_ANYTHING :
case THROBJ_VOID_STAR :
case THROBJ_PTR_FUN :
break;
}
switch( type ) {
case THROBJ_CLASS :
case THROBJ_CLASS_VIRT :
dump( FT_RTN, "ctor-def", sig->clss.ctor
, FT_RTN, "ctor-copy", sig->clss.copyctor
, FT_RTN, "dtor", sig->clss.dtor
, FT_CONT
, FT_OFF, "size", sig->clss.size
, FT_PTR, "name", sig->clss.name
, FT_TEXT, sig->clss.name
, FT_CONT );
break;
case THROBJ_PTR_SCALAR :
if( sig->base.indirect ) {
dump( FT_PTR, "ptr-scalar-indirect", sig->indirected.sig
, FT_CONT );
} else {
dump( FT_OFF, "ptr-scalar size", sig->scalar.size
, FT_CONT );
}
break;
case THROBJ_SCALAR :
dump( FT_OFF, "scalar size", sig->scalar.size
, FT_PTR, "name", sig->scalar.name
, FT_TEXT, sig->scalar.name
, FT_CONT );
break;
case THROBJ_ANYTHING :
printf( " ..." );
break;
case THROBJ_VOID_STAR :
dump( FT_OFF, "void* size", sig->scalar.size
, FT_CONT );
break;
case THROBJ_PTR_FUN :
dump( FT_OFF, "ptr-fun size", sig->scalar.size
, FT_PTR, "name", sig->scalar.name
, FT_TEXT, sig->scalar.name
, FT_CONT );
break;
}
} break;
case FT_TSIGS :
{ unsigned ctr; // - counter
RT_TYPE_SIG *sig; // - type signature list
++indent;
for( ctr = va_arg( args, unsigned ),
sig = va_arg( args, RT_TYPE_SIG* )
; ctr > 0
; --ctr, ++sig ) {
dump( FT_TSIG, *sig
, FT_CONT );
}
--indent;
} break;
case FT_STATE : // state table
{ RO_STATE* state; // - current state
DTOR_CMD* cmd; // - command from state table
size_t index; // - index
state = va_arg( args, RO_STATE* );
dump( FT_PTR, "STATE TABLE", state
, FT_END );
for( index = 1; ; ++state, ++index ) {
if( state->dtor == 0 ) {
cmd = state->u.cmd_addr;
if( cmd == 0 ) break;
dump( FT_OFF, "index", index,
FT_PTR, "cmd", cmd,
FT_CONT );
dumpDtorCmd( rw, cmd );
} else {
dump( FT_OFF, "index", index,
FT_RTN, "dtor", state->dtor,
FT_CONT );
switch( blk_type ) {
case DTRG_FUN :
dump( FT_OFF, "offset", state->u.data_offset,
FT_PTR, "addr",
PointOffset( rw
, state->u.data_offset ),
FT_END );
break;
case DTRG_STATIC_INITLS :
dump( FT_PTR, "addr", state->u.data_addr,
FT_END );
break;
case DTRG_ARRAY :
dump( FT_END );
break;
}
}
}
} break;
case FT_INDENT :
{ unsigned ctr; // - counter
printf( "\n" );
for( ctr = indent; ctr > 0; --ctr ) {
printf( " " );
}
} break;
case FT_CONT :
done = TRUE;
break;
case FT_END :
printf( "\n" );
fflush( __get_std_stream( STDOUT_FILENO ) );
done = TRUE;
break;
}
}
va_end( args );
}
static void dumpObjRegistration(// DUMP RW_DTREG_OBJ, RO_DTREG_OBJ
RW_DTREG_OBJECT* rw, // - R/W block
unsigned offset ) // - offset of component
{
dump( FT_PTR, "RW_OBJ", rw,
FT_PTR, "object", rw->object,
FT_BYTE, "cdtor", rw->cdtor,
FT_PTR, "component", PointOffset( rw->object, offset ),
FT_END );
}
static void dumpArrayInit( // DUMP ARRAY INITIALIZATION
RT_ARRAY_INIT* init ) // - R/W block
{
dump( FT_PTR, "ARRAY-INIT", init
, FT_PTR, "array", init->array
, FT_OFF, "index", init->index
, FT_TSIG, init->sig
, FT_END );
}
static void dumpCmdComponent( // DUMP A COMPONENT COMMAND
RW_DTREG* rw, // - current R/W table
DTOR_CMD* cmd, // - current command
const char* name ) // - command name
{
RW_DTREG_OBJECT* init; // - initialization structure
init = PointUsingOffset( RW_DTREG_OBJECT
, rw
, cmd->component.offset_init );
dump( FT_TEXT, name
, FT_OFF, "off-init", cmd->component.offset_init
, FT_OFF, "off-obj", cmd->component.offset_object
, FT_RTN, "dtor", cmd->component.dtor
, FT_PTR, "add_init", init
, FT_END );
if( CPPLIB( cmd_active )( rw, cmd ) ) {
++indent;
dumpObjRegistration( init, cmd->component.offset_object );
--indent;
}
}
static void dumpDtorCmd( // DUMP DTOR COMMAND
RW_DTREG* rw, // - current R/W table
DTOR_CMD* cmd ) // - current command
{
switch( cmd->base.code ) {
case DTC_CTOR_TEST :
dump( FT_TEXT, "CTOR_TEST"
, FT_OFF, "index", cmd->ctor_test.index
, FT_END );
break;
case DTC_COMP_MEMB :
dumpCmdComponent( rw, cmd, "COMP_MEMB" );
break;
case DTC_COMP_DBASE :
dumpCmdComponent( rw, cmd, "COMP_DBASE" );
break;
case DTC_COMP_VBASE :
dumpCmdComponent( rw, cmd, "COMP_VBASE" );
break;
case DTC_ACTUAL_DBASE :
dumpCmdComponent( rw, cmd, "ACTUAL_DBASE" );
break;
case DTC_ACTUAL_VBASE :
dumpCmdComponent( rw, cmd, "ACTUAL_VBASE" );
break;
case DTC_SET_SV :
dump( FT_TEXT, "SET_SV"
, FT_OFF, "state_var", cmd->set_sv.state_var
, FT_END );
break;
case DTC_TRY :
dump( FT_TEXT, "TRY"
, FT_OFF, "state", cmd->try_cmd.state
, FT_OFF, "jmpbuf", cmd->try_cmd.jmp_buf
, FT_PTR, "addr", PointOffset( rw, cmd->try_cmd.jmp_buf )
, FT_OFF, "offset", cmd->try_cmd.offset
, FT_OFF, "count", cmd->try_cmd.count
, FT_TSIGS, cmd->try_cmd.count, cmd->try_cmd.sigs
, FT_END );
break;
case DTC_CATCH :
dump( FT_TEXT, "CATCH"
, FT_PTR, "try", TryFromCatch( cmd )
, FT_END );
break;
case DTC_FN_EXC :
dump( FT_TEXT, "FN_EXC"
, FT_OFF, "count", cmd->fn_exc.count
, FT_TSIGS, cmd->fn_exc.count, cmd->fn_exc.sigs
, FT_END );
break;
case DTC_TEST_FLAG :
dump( FT_TEXT, "TEST_FLAG"
, FT_OFF, "index", cmd->test_flag.index
, FT_OFF, "sv-true", cmd->test_flag.state_var_true
, FT_OFF, "sv-false", cmd->test_flag.state_var_false
, FT_END );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?