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.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
#define DEBUGGER_MAXROW 22
|
||||
#define DEBUGGER_MAXCOL 77
|
||||
|
||||
STATIC s_oDebugger
|
||||
THREAD STATIC s_oDebugger
|
||||
|
||||
PROCEDURE __dbgAltDEntry()
|
||||
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user