diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 571bbb82bc..1d5bec3365 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,15 @@ past entries belonging to author(s): Viktor Szakats. */ +2010-06-02 12:38 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/src/debug/dbgentry.c + * harbour/src/vm/hvm.c + + added support for breakpoints and file wide static variables + when debugging non main thread. + It finished modifications in debugger code for MT mode. + Probably we should add yet to debugger support for separate + GT window(s) with debugger data for ST and MT applications. + 2010-06-02 10:30 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/src/vm/garbage.c + added new PRG function HB_GCSETAUTO( [] ) -> diff --git a/harbour/src/debug/dbgentry.c b/harbour/src/debug/dbgentry.c index b73664b36e..90372ef908 100644 --- a/harbour/src/debug/dbgentry.c +++ b/harbour/src/debug/dbgentry.c @@ -55,6 +55,7 @@ #include "hbapirdd.h" #include "hbstack.h" #include "hbvm.h" +#include "hbthread.h" #include "hbdebug.ch" #include "hbmacro.ch" @@ -83,6 +84,15 @@ static HB_BOOL hb_clsSetScope( HB_BOOL fScope ) { return fScope; } memmove( array + index, array + index + 1, sizeof( type ) * ( length - index ) ); \ } while( 0 ) +#if 1 +# define HB_DBGCOMMON_LOCK hb_threadEnterCriticalSection( &s_dbgMtx ); +# define HB_DBGCOMMON_UNLOCK hb_threadLeaveCriticalSection( &s_dbgMtx ); + static HB_CRITICAL_NEW( s_dbgMtx ); +#else +# define HB_DBGCOMMON_LOCK +# define HB_DBGCOMMON_UNLOCK +#endif + typedef struct { char * szModule; @@ -140,6 +150,13 @@ typedef struct HB_VARINFO * aExternGlobals; } HB_MODULEINFO; +typedef struct +{ + int nModules; + HB_MODULEINFO * aModules; + PHB_ITEM pStopLines; +} HB_DBGCOMMONINFO; + typedef struct { HB_BOOL bQuit; @@ -161,26 +178,24 @@ typedef struct int nProcLevel; int nCallStackLen; HB_CALLSTACKINFO * aCallStack; - int nModules; - HB_MODULEINFO * aModules; HB_BOOL bCBTrace; HB_BOOL ( *pFunInvoke )( void ); HB_BOOL bInitGlobals; HB_BOOL bInitStatics; HB_BOOL bInitLines; - PHB_ITEM pStopLines; } HB_DEBUGINFO; +static HB_DBGCOMMONINFO s_common = { 0, NULL, NULL }; static PHB_ITEM hb_dbgActivateBreakArray( HB_DEBUGINFO * info ); -static PHB_ITEM hb_dbgActivateModuleArray( HB_DEBUGINFO * info ); +static PHB_ITEM hb_dbgActivateModuleArray( void ); static PHB_ITEM hb_dbgActivateVarArray( int nVars, HB_VARINFO * aVars ); static void hb_dbgAddLocal( HB_DEBUGINFO * info, const char * szName, int nIndex, int nFrame ); -static void hb_dbgAddModule( HB_DEBUGINFO * info, const char * szName ); +static void hb_dbgAddModule( const char * szName ); static void hb_dbgAddStack( HB_DEBUGINFO * info, const char * szName, int nProcLevel ); static void hb_dbgAddStatic( HB_DEBUGINFO * info, const char * szName, int nIndex, PHB_ITEM pFrame ); static void hb_dbgAddVar( int * nVars, HB_VARINFO ** aVars, const char * szName, char cType, int nIndex, int nFrame, PHB_ITEM pFrame ); -static void hb_dbgAddStopLines( HB_DEBUGINFO * info, PHB_ITEM pItem ); +static void hb_dbgAddStopLines( PHB_ITEM pItem ); static void hb_dbgEndProc( HB_DEBUGINFO * info ); static PHB_ITEM hb_dbgEval( HB_DEBUGINFO * info, HB_WATCHPOINT * watch ); static PHB_ITEM hb_dbgEvalMacro( const char * szExpr, PHB_ITEM pItem ); @@ -190,6 +205,7 @@ static HB_BOOL hb_dbgIsAltD( void ); static HB_BOOL hb_dbgIsBreakPoint( HB_DEBUGINFO * info, const char * szModule, int nLine ); static HB_BOOL hb_dbgEqual( PHB_ITEM pItem1, PHB_ITEM pItem2 ); static void hb_dbgQuit( HB_DEBUGINFO * info ); +static void hb_dbgRelease( void ); static PHB_ITEM hb_dbgVarGet( HB_VARINFO * scope ); static void hb_dbgVarSet( HB_VARINFO * scope, PHB_ITEM xNewValue ); @@ -227,7 +243,7 @@ static void hb_dbgActivate( HB_DEBUGINFO * info ) hb_itemRelease( aEntry ); } - aModules = hb_dbgActivateModuleArray( info ); + aModules = hb_dbgActivateModuleArray(); aBreak = hb_dbgActivateBreakArray( info ); hb_vmPushDynSym( pDynSym ); @@ -272,36 +288,43 @@ static PHB_ITEM hb_dbgActivateBreakArray( HB_DEBUGINFO * info ) } -static PHB_ITEM hb_dbgActivateModuleArray( HB_DEBUGINFO * info ) +static PHB_ITEM hb_dbgActivateModuleArray( void ) { + PHB_ITEM pArray; int i; - PHB_ITEM pArray = hb_itemArrayNew( info->nModules ); - for( i = 0; i < info->nModules; i++ ) + HB_DBGCOMMON_LOCK + + pArray = hb_itemArrayNew( s_common.nModules ); + + for( i = 0; i < s_common.nModules; i++ ) { PHB_ITEM pModule = hb_itemArrayNew( 4 ); PHB_ITEM item; - hb_arraySetC( pModule, 1, info->aModules[ i ].szModule ); + hb_arraySetC( pModule, 1, s_common.aModules[ i ].szModule ); - item = hb_dbgActivateVarArray( info->aModules[ i ].nStatics, - info->aModules[ i ].aStatics ); + item = hb_dbgActivateVarArray( s_common.aModules[ i ].nStatics, + s_common.aModules[ i ].aStatics ); hb_arraySet( pModule, 2, item ); hb_itemRelease( item ); - item = hb_dbgActivateVarArray( info->aModules[ i ].nGlobals, - info->aModules[ i ].aGlobals ); + item = hb_dbgActivateVarArray( s_common.aModules[ i ].nGlobals, + s_common.aModules[ i ].aGlobals ); hb_arraySet( pModule, 3, item ); hb_itemRelease( item ); - item = hb_dbgActivateVarArray( info->aModules[ i ].nExternGlobals, - info->aModules[ i ].aExternGlobals ); + item = hb_dbgActivateVarArray( s_common.aModules[ i ].nExternGlobals, + s_common.aModules[ i ].aExternGlobals ); hb_arraySet( pModule, 4, item ); hb_itemRelease( item ); hb_arraySet( pArray, i + 1, pModule ); hb_itemRelease( pModule ); } + + HB_DBGCOMMON_UNLOCK + return pArray; } @@ -369,7 +392,7 @@ void hb_dbgEntry( int nMode, int nLine, const char * szName, int nIndex, PHB_ITE info->bInitLines = HB_TRUE; if( info->bInitStatics || info->bInitGlobals ) - hb_dbgAddModule( info, szName ); + hb_dbgAddModule( szName ); else if( !strncmp( szProcName, "(b)", 3 ) ) info->bCodeBlock = HB_TRUE; else if( info->bNextRoutine ) @@ -506,7 +529,7 @@ void hb_dbgEntry( int nMode, int nLine, const char * szName, int nIndex, PHB_ITE HB_TRACE( HB_TR_DEBUG, ( "ENDPROC %d", nLine ) ); if( info->bInitLines ) - hb_dbgAddStopLines( info, hb_stackReturnItem() ); + hb_dbgAddStopLines( hb_stackReturnItem() ); info->bCodeBlock = HB_FALSE; info->bInitStatics = HB_FALSE; @@ -522,6 +545,11 @@ void hb_dbgEntry( int nMode, int nLine, const char * szName, int nIndex, PHB_ITE hb_xfree( info ); *infoPtr = HB_DBGINFO_DISABLE; } + if( nIndex != 0 ) + { + /* main thread exit and HVM cleanup, release common module info */ + hb_dbgRelease(); + } return; } } @@ -561,9 +589,13 @@ static void hb_dbgAddLocal( HB_DEBUGINFO * info, const char * szName, int nIndex { if( info->bInitGlobals ) { - HB_MODULEINFO *module = &info->aModules[ info->nModules - 1 ]; + HB_MODULEINFO * module; - hb_dbgAddVar( &module->nGlobals, &module->aGlobals, szName, 'G', nIndex, hb_dbg_vmVarGCount(), NULL ); + HB_DBGCOMMON_LOCK + module = &s_common.aModules[ s_common.nModules - 1 ]; + hb_dbgAddVar( &module->nGlobals, &module->aGlobals, szName, + 'G', nIndex, hb_dbg_vmVarGCount(), NULL ); + HB_DBGCOMMON_UNLOCK } else { @@ -574,7 +606,7 @@ static void hb_dbgAddLocal( HB_DEBUGINFO * info, const char * szName, int nIndex } -static void hb_dbgAddModule( HB_DEBUGINFO * info, const char * szName ) +static void hb_dbgAddModule( const char * szName ) { char * szModuleName; const char * szFuncName; @@ -585,17 +617,22 @@ static void hb_dbgAddModule( HB_DEBUGINFO * info, const char * szName ) iLen = szFuncName ? ( int ) ( szFuncName - szName ) : ( int ) strlen( szName ); szModuleName = hb_strndup( szName, iLen ); - if( !info->nModules || strcmp( info->aModules[ info->nModules - 1 ].szModule, szModuleName ) ) + HB_DBGCOMMON_LOCK + if( !s_common.nModules || strcmp( s_common.aModules[ s_common.nModules - 1 ].szModule, szModuleName ) ) { HB_MODULEINFO * pModule; - pModule = ARRAY_ADD( HB_MODULEINFO, info->aModules, info->nModules ); + pModule = ARRAY_ADD( HB_MODULEINFO, s_common.aModules, s_common.nModules ); pModule->szModule = szModuleName; pModule->nStatics = 0; pModule->nGlobals = 0; pModule->nExternGlobals = 0; + + szModuleName = NULL; } - else + HB_DBGCOMMON_UNLOCK + + if( szModuleName ) hb_xfree( szModuleName ); } @@ -648,16 +685,23 @@ static void hb_dbgAddStatic( HB_DEBUGINFO * info, const char * szName, int nInde { if( info->bInitGlobals ) { - HB_MODULEINFO *module = &info->aModules[ info->nModules - 1 ]; + HB_MODULEINFO * module; + HB_DBGCOMMON_LOCK + module = &s_common.aModules[ s_common.nModules - 1 ]; hb_dbgAddVar( &module->nExternGlobals, &module->aExternGlobals, szName, 'G', nIndex, hb_dbg_vmVarGCount(), NULL ); + HB_DBGCOMMON_UNLOCK } else if( info->bInitStatics ) { - HB_MODULEINFO *module = &info->aModules[ info->nModules - 1 ]; + HB_MODULEINFO * module; - hb_dbgAddVar( &module->nStatics, &module->aStatics, szName, 'S', nIndex, 0, pFrame ); + HB_DBGCOMMON_LOCK + module = &s_common.aModules[ s_common.nModules - 1 ]; + hb_dbgAddVar( &module->nStatics, &module->aStatics, szName, + 'S', nIndex, 0, pFrame ); + HB_DBGCOMMON_UNLOCK } else { @@ -668,20 +712,22 @@ static void hb_dbgAddStatic( HB_DEBUGINFO * info, const char * szName, int nInde } -static void hb_dbgAddStopLines( HB_DEBUGINFO * info, PHB_ITEM pItem ) +static void hb_dbgAddStopLines( PHB_ITEM pItem ) { int i, nLinesLen; - if( !info->pStopLines ) + HB_DBGCOMMON_LOCK + + if( !s_common.pStopLines ) { - info->pStopLines = hb_itemNew( pItem ); + s_common.pStopLines = hb_itemNew( pItem ); } else { int j; int nItemLen = hb_itemSize( pItem ); - nLinesLen = hb_itemSize( info->pStopLines ); + nLinesLen = hb_itemSize( s_common.pStopLines ); for( i = 1; i <= nItemLen; i++ ) { @@ -692,7 +738,7 @@ static void hb_dbgAddStopLines( HB_DEBUGINFO * info, PHB_ITEM pItem ) szModule = hb_dbgStripModuleName( szModule ); for( j = 1; j <= nLinesLen; j++ ) { - PHB_ITEM pLines = hb_arrayGetItemPtr( info->pStopLines, j ); + PHB_ITEM pLines = hb_arrayGetItemPtr( s_common.pStopLines, j ); if( !strcmp( hb_arrayGetCPtr( pLines, 1 ), szModule ) ) { @@ -729,13 +775,13 @@ static void hb_dbgAddStopLines( HB_DEBUGINFO * info, PHB_ITEM pItem ) } if( !bFound ) - hb_arrayAddForward( info->pStopLines, pEntry ); + hb_arrayAddForward( s_common.pStopLines, pEntry ); } } - nLinesLen = hb_itemSize( info->pStopLines ); + nLinesLen = hb_itemSize( s_common.pStopLines ); for( i = 1; i <= nLinesLen; i++ ) { - PHB_ITEM pEntry = hb_arrayGetItemPtr( info->pStopLines, i ); + PHB_ITEM pEntry = hb_arrayGetItemPtr( s_common.pStopLines, i ); const char * szModule = hb_arrayGetCPtr( pEntry, 1 ); if( szModule ) @@ -746,6 +792,8 @@ static void hb_dbgAddStopLines( HB_DEBUGINFO * info, PHB_ITEM pItem ) hb_arraySetCLPtr( pEntry, 1, hb_strdup( szName ), ( HB_SIZE ) strlen( szName ) ); } } + + HB_DBGCOMMON_UNLOCK } @@ -1166,11 +1214,13 @@ static PHB_ITEM hb_dbgEvalResolve( HB_DEBUGINFO * info, HB_WATCHPOINT * watch ) scopes = ( HB_VARINFO * ) hb_xgrab( watch->nVars * sizeof( HB_VARINFO ) ); nProcLevel = hb_dbg_ProcLevel(); - for( i = 0; i < info->nModules; i++ ) + HB_DBGCOMMON_LOCK + + for( i = 0; i < s_common.nModules; i++ ) { - if( !strcmp( info->aModules[ i ].szModule, top->szModule ) ) + if( !strcmp( s_common.aModules[ i ].szModule, top->szModule ) ) { - module = &info->aModules[ i ]; + module = &s_common.aModules[ i ]; break; } } @@ -1272,6 +1322,9 @@ static PHB_ITEM hb_dbgEvalResolve( HB_DEBUGINFO * info, HB_WATCHPOINT * watch ) hb_itemRelease( pItem ); } watch->aScopes = scopes; + + HB_DBGCOMMON_UNLOCK + return aVars; } @@ -1296,13 +1349,19 @@ PHB_ITEM hb_dbgGetExpressionValue( void * handle, const char *expression ) PHB_ITEM hb_dbgGetSourceFiles( void * handle ) { - HB_DEBUGINFO * info = ( HB_DEBUGINFO * ) handle; - int nModules = hb_itemSize( info->pStopLines ); - PHB_ITEM ret = hb_itemArrayNew( nModules ); + PHB_ITEM ret; + int nModules; int i; + /* HB_DEBUGINFO * info = ( HB_DEBUGINFO * ) handle; */ + HB_SYMBOL_UNUSED( handle ); + + HB_DBGCOMMON_LOCK + nModules = hb_itemSize( s_common.pStopLines ); + ret = hb_itemArrayNew( nModules ); for( i = 1; i <= nModules; i++ ) - hb_arraySet( ret, i, hb_arrayGetItemPtr( hb_arrayGetItemPtr( info->pStopLines, i ), 1 ) ); + hb_arraySet( ret, i, hb_arrayGetItemPtr( hb_arrayGetItemPtr( s_common.pStopLines, i ), 1 ) ); + HB_DBGCOMMON_UNLOCK return ret; } @@ -1343,26 +1402,32 @@ static HB_BOOL hb_dbgIsBreakPoint( HB_DEBUGINFO * info, const char * szModule, i HB_BOOL hb_dbgIsValidStopLine( void * handle, const char * szModule, int nLine ) { - HB_DEBUGINFO * info = ( HB_DEBUGINFO * ) handle; - int nModules = hb_itemSize( info->pStopLines ); + HB_BOOL fResult = HB_FALSE; + int nModules; int i; + /* HB_DEBUGINFO * info = ( HB_DEBUGINFO * ) handle; */ + HB_SYMBOL_UNUSED( handle ); + + HB_DBGCOMMON_LOCK + nModules = hb_itemSize( s_common.pStopLines ); for( i = 1; i <= nModules; i++ ) { - PHB_ITEM pEntry = hb_arrayGetItemPtr( info->pStopLines, i ); + PHB_ITEM pEntry = hb_arrayGetItemPtr( s_common.pStopLines, i ); if( FILENAME_EQUAL( hb_arrayGetCPtr( pEntry, 1 ), szModule ) ) { int nMin = hb_arrayGetNL( pEntry, 2 ); int nOfs = nLine - nMin; - if( nOfs < 0 || ( HB_SIZE ) ( nOfs >> 3 ) >= hb_arrayGetCLen( pEntry, 3 ) ) - return HB_FALSE; + if( nOfs >= 0 && ( HB_SIZE ) ( nOfs >> 3 ) < hb_arrayGetCLen( pEntry, 3 ) ) + fResult = ( hb_arrayGetCPtr( pEntry, 3 )[ nOfs >> 3 ] & ( 1 << ( nOfs & 0x07 ) ) ) != 0; - return ( hb_arrayGetCPtr( pEntry, 3 )[ nOfs >> 3 ] & ( 1 << ( nOfs & 0x07 ) ) ) != 0; + break; } } - return HB_FALSE; + HB_DBGCOMMON_UNLOCK + return fResult; } @@ -1380,14 +1445,25 @@ static void hb_dbgQuit( HB_DEBUGINFO * info ) { hb_dbgEndProc( info ); } - if( info->pStopLines ) + if( info->bToCursor ) { - hb_itemRelease( info->pStopLines ); + info->bToCursor = HB_FALSE; + hb_xfree( info->szToCursorModule ); } - while( info->nModules ) +} + + +static void hb_dbgRelease( void ) +{ + if( s_common.pStopLines ) { - int nModules = info->nModules - 1; - HB_MODULEINFO *module = &info->aModules[ nModules ]; + hb_itemRelease( s_common.pStopLines ); + s_common.pStopLines = NULL; + } + while( s_common.nModules ) + { + int nModules = s_common.nModules - 1; + HB_MODULEINFO *module = &s_common.aModules[ nModules ]; if( module->nStatics ) { hb_xfree( module->aStatics ); @@ -1404,12 +1480,7 @@ static void hb_dbgQuit( HB_DEBUGINFO * info ) { hb_xfree( module->szModule ); } - ARRAY_DEL( HB_MODULEINFO, info->aModules, info->nModules, nModules ); - } - if( info->bToCursor ) - { - info->bToCursor = HB_FALSE; - hb_xfree( info->szToCursorModule ); + ARRAY_DEL( HB_MODULEINFO, s_common.aModules, s_common.nModules, nModules ); } } diff --git a/harbour/src/vm/hvm.c b/harbour/src/vm/hvm.c index 34290c0e0e..73710440a4 100644 --- a/harbour/src/vm/hvm.c +++ b/harbour/src/vm/hvm.c @@ -6194,7 +6194,8 @@ static void hb_vmDebugEntry( int nMode, int nLine, const char *szName, int nInde hb_vmPushDynSym( s_pDynsDbgEntry ); hb_vmPushNil(); hb_vmPushInteger( HB_DBG_VMQUIT ); - hb_vmProc( 1 ); + hb_vmPushInteger( nIndex ); + hb_vmProc( 2 ); break; } } @@ -6218,7 +6219,7 @@ static void hb_vmDebuggerExit( HB_BOOL fRemove ) if( s_pFunDbgEntry ) { /* inform debugger that we are quitting now */ - s_pFunDbgEntry( HB_DBG_VMQUIT, 0, NULL, 0, NULL ); + s_pFunDbgEntry( HB_DBG_VMQUIT, 0, NULL, fRemove ? 1 : 0, NULL ); /* set dummy debugger function to avoid debugger activation in .prg * destructors if any */ if( fRemove )