diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 538fb01031..938a14b1c8 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,27 @@ 2008-12-31 13:59 UTC+0100 Foo Bar (foo.bar foobar.org) */ +2008-10-15 17:50 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/include/hbstack.h + * harbour/source/vm/estack.c + * harbour/source/vm/hvm.c + * harbour/source/debug/dbgentry.c + * harbour/source/debug/debugger.prg + * moved debugRequest flag and debugger internal structure + pointer to HVM stack + * allocate debugger internal structure dynamically in thread + thread local area when PCODE with debug information is executed + * changed STATIC s_oDebugger to THREAD STATIC + * send HB_DBG_VMQUIT after each thread termination when + debugger is activated + Now debugger can be used in MT programs and each thread can be + debugged separately (each has its own debuger). Please only + remember that thread sharing console window can overwrite other + threads debugger screen. There is also one limitation which I'll + try to remove later: only main thread debugger keeps information + about file wide STATIC names and line numbers with possible break + point places. This data should be shared between debuggers. + 2008-10-15 13:32 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/include/hbapi.h * harbour/source/vm/hvm.c diff --git a/harbour/include/hbstack.h b/harbour/include/hbstack.h index 701ba02c0b..531e6c3550 100644 --- a/harbour/include/hbstack.h +++ b/harbour/include/hbstack.h @@ -168,16 +168,13 @@ typedef struct char szDate[ 9 ]; /* last returned date from _pards() yyyymmdd format */ void * pCDP; /* current codepage module */ void * pLang; /* current language module */ - const char * szDefaultRDD; /* default RDD */ - int iArea; /* current workarea number */ - int iAreaCount; /* number of allocated workareas number */ - void ** pWorkAreas; /* workareas pool */ - BOOL fNetErr; /* current NETERR() flag */ int iTSD; /* number of allocated TSD holders */ PHB_TSD_HOLDER pTSD; /* thread specific data holder */ HB_PRIVATE_STACK privates; /* private variables stack */ HB_SET_STRUCT set; int iKeyPoll; /* counter for GT/keyboard polling */ + int fDebugRequest; /* request debugger activation */ + void * pDebugInfo; /* internal debugger structure */ #if defined( HB_MT_VM ) int iUnlocked; /* counter for nested hb_vmUnlock() calls */ PHB_DYN_HANDLES pDynH; /* dynamic symbol handles */ @@ -288,6 +285,8 @@ extern BYTE * hb_stackDirBuffer( void ); extern PHB_IOERRORS hb_stackIOErrors( void ); extern PHB_STACKRDD hb_stackRDD( void ); +extern void ** hb_stackDebugInfo( void ); + #ifdef _HB_API_INTERNAL_ extern void hb_stackDecrease( ULONG ulItems ); extern HB_ITEM_PTR hb_stackNewFrame( PHB_STACK_STATE pFrame, USHORT uiParams ); @@ -310,6 +309,7 @@ extern LONG hb_stackWithObjectOffset( void ); extern void hb_stackWithObjectSetOffset( LONG ); extern int * hb_stackKeyPolls( void ); +extern BOOL * hb_stackDebugRequest( void ); extern void hb_stackDestroyTSD( void ); @@ -446,6 +446,8 @@ extern void hb_stackIsStackRef( void *, PHB_TSD_FUNC ); #define hb_stackGetPrivateStack( ) ( &hb_stack.privates ) #define hb_stackSetStruct( ) ( &hb_stack.set ) #define hb_stackKeyPolls( ) ( &hb_stack.iKeyPoll ) +#define hb_stackDebugRequest( ) ( &hb_stack.fDebugRequest ) +#define hb_stackDebugInfo( ) ( &hb_stack.pDebugInfo ) #endif diff --git a/harbour/source/debug/dbgentry.c b/harbour/source/debug/dbgentry.c index 3197016fa2..dcbc71d3a0 100644 --- a/harbour/source/debug/dbgentry.c +++ b/harbour/source/debug/dbgentry.c @@ -64,6 +64,8 @@ /* dummy function declaration */ static BOOL hb_clsSetScope( BOOL fScope ) { return fScope; } +#define HB_DBGINFO_DISABLE ( ( HB_DEBUGINFO * ) ( HB_PTRDIFF ) 0x01 ) + #if defined( HB_OS_UNIX_COMPATIBLE ) #define FILENAME_EQUAL(s1, s2) ( !strcmp( (s1), (s2) ) ) #else @@ -173,10 +175,6 @@ typedef struct } HB_DEBUGINFO; -static HB_DEBUGINFO s_Info = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* bCBTrace */ TRUE, 0, 0, 0, 0, 0 }; -static HB_DEBUGINFO *s_pInfo = &s_Info; - - static PHB_ITEM hb_dbgActivateBreakArray( HB_DEBUGINFO *info ); static PHB_ITEM @@ -364,10 +362,22 @@ hb_dbgEntry( int nMode, int nLine, char *szName, int nIndex, int nFrame ) int i; ULONG nProcLevel; char szProcName[ HB_SYMBOL_NAME_LEN + HB_SYMBOL_NAME_LEN + 5 ]; - HB_DEBUGINFO *info = s_pInfo; + HB_DEBUGINFO ** infoPtr = ( HB_DEBUGINFO ** ) hb_stackDebugInfo(); + HB_DEBUGINFO *info = *infoPtr; - if ( ( info->bInside || info->bQuit ) && nMode != HB_DBG_VMQUIT ) + if( info == HB_DBGINFO_DISABLE ) return; + else if ( nMode != HB_DBG_VMQUIT ) + { + if( !info ) + { + info = *infoPtr = ( HB_DEBUGINFO * ) ALLOC( sizeof( HB_DEBUGINFO ) ); + memset( info, 0, sizeof( HB_DEBUGINFO ) ); + info->bCBTrace = TRUE; + } + else if ( info->bInside || info->bQuit ) + return; + } switch ( nMode ) { @@ -536,7 +546,12 @@ hb_dbgEntry( int nMode, int nLine, char *szName, int nIndex, int nFrame ) return; case HB_DBG_VMQUIT: - hb_dbgQuit( info ); + if( info ) + { + hb_dbgQuit( info ); + FREE( info ); + *infoPtr = HB_DBGINFO_DISABLE; + } return; } } diff --git a/harbour/source/debug/debugger.prg b/harbour/source/debug/debugger.prg index 6c1955fc9b..9e478a1b41 100644 --- a/harbour/source/debug/debugger.prg +++ b/harbour/source/debug/debugger.prg @@ -108,7 +108,7 @@ #define DEBUGGER_MAXROW 22 #define DEBUGGER_MAXCOL 77 -STATIC s_oDebugger +THREAD STATIC s_oDebugger PROCEDURE __dbgAltDEntry() diff --git a/harbour/source/vm/estack.c b/harbour/source/vm/estack.c index 5a06f13afd..c5f64f00b3 100644 --- a/harbour/source/vm/estack.c +++ b/harbour/source/vm/estack.c @@ -432,6 +432,26 @@ int * hb_stackKeyPolls( void ) return &hb_stack.iKeyPoll; } +#undef hb_stackDebugRequest +BOOL * hb_stackDebugRequest( void ) +{ + HB_STACK_TLS_PRELOAD + + HB_TRACE(HB_TR_DEBUG, ("hb_stackDebugRequest()")); + + return &hb_stack.fDebugRequest; +} + +#undef hb_stackDebugInfo +void ** hb_stackDebugInfo( void ) +{ + HB_STACK_TLS_PRELOAD + + HB_TRACE(HB_TR_DEBUG, ("hb_stackDebugInfo()")); + + return &hb_stack.pDebugInfo; +} + #undef hb_stackGetPrivateStack PHB_PRIVATE_STACK hb_stackGetPrivateStack( void ) { diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index ca977ee81c..223f79112a 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -216,11 +216,10 @@ static void hb_vmStaticName( BYTE bIsGlobal, USHORT uiStatic, char * szStatic static void hb_vmModuleName( char * szModuleName ); /* PRG and function name information for the debugger */ static void hb_vmDebugEntry( int nMode, int nLine, char *szName, int nIndex, int nFrame ); -static void hb_vmDebuggerExit( void ); /* shuts down the debugger */ +static void hb_vmDebuggerExit( BOOL fRemove ); /* shuts down the debugger */ static void hb_vmDebuggerShowLine( USHORT uiLine ); /* makes the debugger shows a specific source code line */ static void hb_vmDebuggerEndProc( void ); /* notifies the debugger for an endproc */ -static BOOL s_bDebugRequest = FALSE; /* debugger invoked via the VM */ static PHB_DYNS s_pDynsDbgEntry = NULL; /* Cached __DBGENTRY symbol */ static HB_DBGENTRY_FUNC s_pFunDbgEntry; /* C level debugger entry */ #endif @@ -808,9 +807,13 @@ HB_EXPORT void hb_vmThreadQuit( void ) } hb_itemClear( hb_stackReturnItem() ); + hb_stackSetActionRequest( 0 ); hb_rddCloseAll(); /* close all workareas */ hb_stackRemove( 1 ); /* clear stack items, leave only initial symbol item */ hb_memvarsClear(); /* clear all PUBLIC (and PRIVATE if any) variables */ +#ifndef HB_NO_DEBUG + hb_vmDebuggerExit( FALSE ); /* deactivate debugger */ +#endif hb_vmStackRelease(); /* release HVM stack and remove it from linked HVM stacks list */ } @@ -1010,11 +1013,6 @@ HB_EXPORT int hb_vmQuit( void ) hb_vmDoModuleExitFunctions(); hb_vmCleanModuleFunctions(); -#ifndef HB_NO_DEBUG - /* deactivate debugger */ - hb_vmDebuggerExit(); -#endif - /* release all known items stored in subsystems */ hb_itemClear( hb_stackReturnItem() ); hb_stackRemove( 1 ); /* clear stack items, leave only initial symbol item */ @@ -1033,6 +1031,11 @@ HB_EXPORT int hb_vmQuit( void ) hb_rddCloseAll(); /* close all workareas */ hb_rddShutDown(); /* remove all registered RDD drivers */ +#ifndef HB_NO_DEBUG + /* deactivate debugger */ + hb_vmDebuggerExit( TRUE ); +#endif + /* release thread specific data */ hb_stackDestroyTSD(); @@ -5717,9 +5720,9 @@ static void hb_vmDummyDebugEntry( int nMode, int nLine, char *szName, int nIndex HB_SYMBOL_UNUSED( nFrame ); } -static void hb_vmDebuggerExit( void ) +static void hb_vmDebuggerExit( BOOL fRemove ) { - HB_TRACE(HB_TR_DEBUG, ("hb_vmDebuggerExit")); + HB_TRACE(HB_TR_DEBUG, ("hb_vmDebuggerExit(%d)", fRemove)); /* is debugger linked ? */ if( s_pFunDbgEntry ) @@ -5728,7 +5731,8 @@ static void hb_vmDebuggerExit( void ) s_pFunDbgEntry( HB_DBG_VMQUIT, 0, NULL, 0, 0 ); /* set dummy debugger function to avoid debugger activation in .prg * destructors if any */ - s_pFunDbgEntry = hb_vmDummyDebugEntry; + if( fRemove ) + s_pFunDbgEntry = hb_vmDummyDebugEntry; } } @@ -10561,17 +10565,22 @@ HB_EXPORT void hb_vmFlagClear( ULONG flags ) void hb_vmRequestDebug( void ) { - HB_TRACE(HB_TR_DEBUG, ("hb_vmRequestDebug()")); #ifndef HB_NO_DEBUG - s_bDebugRequest = TRUE; + HB_STACK_TLS_PRELOAD + + HB_TRACE(HB_TR_DEBUG, ("hb_vmRequestDebug()")); + + *( hb_stackDebugRequest() ) = TRUE; #endif } HB_EXPORT BOOL hb_dbg_InvokeDebug( BOOL bInvoke ) { #ifndef HB_NO_DEBUG - BOOL bRequest = s_bDebugRequest; - s_bDebugRequest = bInvoke; + HB_STACK_TLS_PRELOAD + BOOL * pfRequest = hb_stackDebugRequest(); + BOOL bRequest = *pfRequest; + *pfRequest = bInvoke; return bRequest; #else HB_SYMBOL_UNUSED( bInvoke ); @@ -10615,8 +10624,10 @@ HB_FUNC( __DBGINVOKEDEBUG ) HB_STACK_TLS_PRELOAD #ifndef HB_NO_DEBUG - hb_retl( s_bDebugRequest ); - s_bDebugRequest = hb_parl( 1 ); + BOOL * pfRequest = hb_stackDebugRequest(); + + hb_retl( *pfRequest ); + *pfRequest = hb_parl( 1 ); #else hb_retl( FALSE ); #endif