123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- #include "bbdebug.h"
- #include "bbarray.h"
- #include <bbmonkey.h>
- #if _WIN32
- #include <windows.h>
- #include <thread>
- #else
- #include <signal.h>
- #endif
- typedef void(*dbEmit_t)(void*);
- namespace bbDB{
- int nextSeq;
-
- bbDBContext *currentContext;
-
- #if !_WIN32
- void breakHandler( int sig ){
- currentContext->stopped=0x10000000;
- }
- #endif
- void sighandler( int sig ){
-
- const char *err="Unknown signal";
- switch( sig ){
- case SIGSEGV:err="Memory access violation";break;
- case SIGILL:err="Illegal instruction";
- case SIGFPE:err="Floating point exception";
- #if !_WIN32
- case SIGBUS:err="Bus error";
- #endif
- }
-
- #ifndef NDEBUG
- error( err );
- exit( 0 );
- #endif
- bb_printf( "Caught signal:%s\n",err );
- exit( -1 );
- }
-
- void init(){
-
- currentContext=new bbDBContext;
- currentContext->init();
-
- signal( SIGSEGV,sighandler );
- signal( SIGILL,sighandler );
- signal( SIGFPE,sighandler );
- #if !_WIN32
- signal( SIGBUS,sighandler );
- #endif
- #ifndef NDEBUG
-
- #if _WIN32
- if( HANDLE breakEvent=OpenEvent( EVENT_ALL_ACCESS,false,"MX2_BREAK_EVENT" ) ){
- // bb_printf( "Found BREAK_EVENT!\n" );fflush( stdout );
- std::thread( [=](){
- for( ;; ){
- WaitForSingleObject( breakEvent,INFINITE );
- // bb_printf( "Break event!\n" );fflush( stdout );
- currentContext->stopped=0x10000000;
- }
- } ).detach();
- }
- #else
- signal( SIGTSTP,breakHandler );
- #endif
- #endif
- }
-
- void emitVar( bbDBVar *v ){
- bbString id=v->name;
- bbString type=v->type->type();
- bbString value=v->type->value( v->var );
- bbString t=id+":"+type+"="+value+"\n";
- bb_printf( "%s",t.c_str() );
- }
-
- void emitStack(){
- bbDBVar *ev=currentContext->locals;
-
- for( bbDBFrame *f=currentContext->frames;f;f=f->succ ){
- bb_printf( ">%s;%s;%i;%i\n",f->decl,f->srcFile,f->srcPos>>12,f->seq );
-
- for( bbDBVar *v=f->locals;v!=ev;++v ){
- emitVar( v );
- }
- ev=f->locals;
- }
- }
-
- void stop(){
- currentContext->stopped=0;
- }
-
- void emit( const char *e ){
-
- if( const char *p=strchr( e,':' ) ){
- dbEmit_t dbEmit=(dbEmit_t)( strtol( p+1,0,16 ) );
- dbEmit( (void*)strtol( e,0,16 ) );
- }else{
- bbGCNode *node=(bbGCNode*)strtol( e,0,16 );
- node->dbEmit();
- }
-
- puts( "" );
- fflush( stdout );
- }
-
- void stopped(){
- bb_printf( "{{!DEBUG!}}\n" );
-
- emitStack();
- bb_printf( "\n" );
- fflush( stdout );
-
- for(;;){
-
- char buf[256];
- char *e=fgets( buf,256,stdin );
- if( !e ) exit( -1 );
-
- switch( e[0] ){
- case 's':currentContext->stopped=0;return;
- case 'e':currentContext->stopped=1;return;
- case 'l':currentContext->stopped=-1;return;
- case 'r':currentContext->stopped=-0x10000000;return;
- case '@':emit( e+1 );continue;
- case 'q':exit( 0 );return;
- }
- bb_printf( "Unrecognized debug cmd: %s\n",buf );fflush( stdout );
- exit( -1 );
- }
- }
-
- void error( bbString msg ){
-
- bb_printf( "\n%s\n",msg.c_str() );
- stopped();
- }
-
- bbArray<bbString> stack(){
-
- int n=0;
- for( bbDBFrame *frame=currentContext->frames;frame;frame=frame->succ ) ++n;
-
- //TODO: Fix GC issues! Can't have a free local like this in case bbString ctors cause gc sweep!!!!
- bbArray<bbString> st=bbArray<bbString>( n );
-
- int i=0;
- for( bbDBFrame *frame=currentContext->frames;frame;frame=frame->succ ){
- st[i++]=BB_T( frame->srcFile )+" ["+bbString( frame->srcPos>>12 )+"] "+frame->decl;
- }
-
- return st;
- }
- }
- void bbDBContext::init(){
- if( !localsBuf ) localsBuf=new bbDBVar[16384];
- locals=localsBuf;
- frames=nullptr;
- stopped=0;
- }
- bbDBContext::~bbDBContext(){
- delete[] localsBuf;
- }
- bbString bbDBValue( bbString *p ){
- bbString t=*p,dd="";
- if( t.length()>100 ){
- t=t.slice( 0,100 );
- dd="...";
- }
- t=t.replace( "\"","~q" );
- t=t.replace( "\n","~n" );
- t=t.replace( "\r","~r" );
- t=t.replace( "\t","~t" );
- return BB_T("\"")+t+"\""+dd;
- }
|