📄 control.cpp
字号:
/****************************************************************************
*
* 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!
*
****************************************************************************/
#include <windows.h>
#include <malloc.h>
#include <string.h>
#include <stdio.h>
#include "machtype.h"
#include "trapbrk.h"
#include "trperr.h"
#include "msjvdbg.h"
#include "jdbgguid.h"
#include "msvmutil.h"
#include "msjutil.h"
#include "control.h"
#include "readwr.h"
#include "madjvm.h"
#include "olemap.hpp"
class WDbgMgrCallback : public IRemoteDebugManagerCallback {
public:
unsigned refcount;
virtual HRESULT __stdcall QueryInterface( REFIID, void ** );
virtual ULONG __stdcall AddRef( void );
virtual ULONG __stdcall Release( void );
virtual HRESULT __stdcall ProcessCreateEvent( IRemoteProcess * newproc,
IRemoteProcess * parent );
};
class WProcessCallback : public IRemoteProcessCallback {
public:
unsigned refcount;
virtual HRESULT __stdcall QueryInterface( REFIID, void ** );
virtual ULONG __stdcall AddRef( void );
virtual ULONG __stdcall Release( void );
virtual HRESULT __stdcall DebugStringEvent( IRemoteThread *,
LPCOLESTR );
virtual HRESULT __stdcall CodeBreakpointEvent( IRemoteThread * );
virtual HRESULT __stdcall DataBreakpointEvent( IRemoteThread *,
IRemoteObject * );
virtual HRESULT __stdcall ExceptionEvent( IRemoteThread *,
IRemoteClassField *,
EXCEPTIONKIND );
virtual HRESULT __stdcall StepEvent( IRemoteThread * );
virtual HRESULT __stdcall CanStopEvent( IRemoteThread * );
virtual HRESULT __stdcall BreakEvent( IRemoteThread * );
virtual HRESULT __stdcall ThreadCreateEvent( IRemoteThread * );
virtual HRESULT __stdcall ThreadDestroyEvent( IRemoteThread * );
virtual HRESULT __stdcall ThreadGroupCreateEvent( IRemoteThread *,
IRemoteThreadGroup * );
virtual HRESULT __stdcall ThreadGroupDestroyEvent( IRemoteThread *,
IRemoteThreadGroup * );
virtual HRESULT __stdcall ClassLoadEvent( IRemoteThread *,
IRemoteClassField * );
virtual HRESULT __stdcall ClassUnloadEvent( IRemoteThread *,
IRemoteClassField * );
virtual HRESULT __stdcall ProcessDestroyEvent( IRemoteThread * );
virtual HRESULT __stdcall TraceEvent( IRemoteThread * );
virtual HRESULT __stdcall LoadCompleteEvent( IRemoteThread * );
};
#define MAX_HWNDS 40 // maximum number of hwnds in the debugger
static IRemoteDebugManager * DbgManager;
static WDbgMgrCallback ManagerCB;
static WProcessCallback ProcessCB;
static HWND InvalidHWNDs[MAX_HWNDS];
static int NumInvalid = 0;
static HANDLE EventSem;
typedef struct _threadlist {
struct _threadlist *next;
IRemoteThread * handle;
char * name; // variable length structure
} threadlist;
static struct {
IRemoteProcess * curr;
HANDLE termthread;
HANDLE prochdl;
unsigned flags;
threadlist * threadtable;
unsigned waiting : 1;
unsigned interrupting : 1;
unsigned task_loading : 1;
} Process;
struct ImageEntry {
IRemoteClassField *cls;
char *className;
ULONG num_methods;
IRemoteMethodField **methods;
ULONG num_cues;
jvm_line_info *cues;
ULONG base_addr;
ULONG end_addr;
IEnumRemoteField *pEnum;
unsigned newly_loaded : 1;
unsigned newly_unloaded : 1;
unsigned modinfo_loaded : 1;
unsigned addrinfo_loaded : 1;
unsigned cues_loaded : 1;
};
#define MAKE_OFFSET( i,m,o ) ( ( ( ((i)+1) & 0xFF) << 24 ) + ( ( (m) & 0xFF ) << 16 ) + (o) )
#define OFFSET_IMAGE( a ) ( ( ( (a) >> 24 ) & 0xFF ) - 1 )
#define OFFSET_METHOD( a ) ( ( (a) >> 16 ) & 0xFF )
#define OFFSET_OFFSET( a ) ( (a) & 0xFFFF )
int __assert( char *str, char *file, int line )
{
char buff[256];
sprintf( buff, "%s(%d): %s", file, line, str );
MessageBox( NULL, buff, "Assertion Failed", MB_SYSTEMMODAL+MB_OK );
return( 0 );
}
int __ok()
{
return( 1 );
}
#define DbgAssert( x ) ( (x) ? __ok() : __assert( #x, __FILE__, __LINE__ ) )
#define MustSucceed( x ) DbgAssert( SUCCEEDED( x ) )
#define MustBeMainThread() DbgAssert( MainThreadId == GetCurrentThreadId() )
static ImageEntry *ImageMap;
static int ImageMapSize;
static int ImageMapTop;
LPSTREAM CurrThreadStream;
IRemoteThread * CurrThread;
IRemoteThread * TraceThread;
IRemoteThread * CurrThread_T2;
// function prototypes
static DWORD WINAPI WaitForDeath( void * );
static void WaitForEvent( void );
static void SignalEvent( void );
extern "C" {
extern HWND DebuggerWindow;
static DWORD MainThreadId;
extern bool InitProc( void )
/**************************/
{
EventSem = CreateSemaphore( NULL, 0, 1, NULL );
ManagerCB.refcount = 0;
ProcessCB.refcount = 0;
MainThreadId = GetCurrentThreadId();
if( !SUCCEEDED( CoInitialize( NULL ) ) ) return( FALSE );
if( !SUCCEEDED( CoCreateInstance( CLSID_RemoteJavaDebugManager, NULL,
CLSCTX_LOCAL_SERVER, IID_IRemoteDebugManager,
(PVOID *)&DbgManager ) ) ) return FALSE;
DbgManager->AddRef();
return( SUCCEEDED( DbgManager->RegisterCallback( &ManagerCB ) ) );
}
extern void FiniProc( void )
/**************************/
{
MustBeMainThread();
if( DbgManager != NULL ) {
DbgManager->Detach();
DbgManager->Release();
}
CoUninitialize();
CloseHandle( EventSem );
}
extern void TraceOn( void )
/*************************/
{
MustBeMainThread();
Process.curr->TraceMethods( TRUE );
}
extern void TraceOff( void )
/**************************/
{
MustBeMainThread();
Process.curr->TraceMethods( FALSE );
}
#define CLASSNAME_SUFFIX " [Class]"
extern HANDLE FakeOpen( char *name )
/*******************************/
{
int len = strlen( name );
if( len > sizeof( CLASSNAME_SUFFIX ) - 1 ) {
if( strcmp( name + len - sizeof( CLASSNAME_SUFFIX ) + 1, CLASSNAME_SUFFIX ) == 0 ) {
return( FakeHandle );
}
}
return( INVALID_HANDLE_VALUE );
}
static int LastNameGiven;
extern bool FakeRead( HANDLE h, void* buff, unsigned len, unsigned*amtRead )
/**************************************************************************/
{
char *data;
if( h != FakeHandle ) return( FALSE );
data = "JAVAxxxx";
*(int*)(data+4)=LastNameGiven;
if( len > 8 ) len = 8;
memcpy( buff, data, len );
if( amtRead ) *amtRead = len;
return( TRUE );
}
void AddAddressInfo( int idx )
/****************************/
{
IRemoteClassField *cls;
ImageEntry *image;
image = &ImageMap[idx];
if( image->addrinfo_loaded ) return;
MustBeMainThread();
image->addrinfo_loaded = TRUE;
cls = image->cls;
if( !SUCCEEDED( cls->GetFields(&image->pEnum,FIELD_KIND_METHOD,0,NULL) ) ) return;
image->pEnum->GetCount( &image->num_methods );
image->base_addr = MAKE_OFFSET( idx, 0, 0 );
image->end_addr = MAKE_OFFSET( idx, image->num_methods-1, 0xFFFF );
}
void AddModuleInfo( int idx )
/**************************/
{
ULONG got, fetched;
IRemoteField *field;
IRemoteMethodField *meth;
ImageEntry *image;
image = &ImageMap[idx];
if( image->modinfo_loaded ) return;
MustBeMainThread();
image->modinfo_loaded = TRUE;
AddAddressInfo( idx );
image->methods = (IRemoteMethodField**)MSJAlloc( image->num_methods * sizeof( IRemoteField* ) );
got = 0;
while( got < image->num_methods ) {
image->pEnum->Next( 1, &field, &fetched );
field->QueryInterface( IID_IRemoteMethodField, (void**)&meth );
image->methods[got] = meth;
field->Release();
got += fetched;
}
image->pEnum->Release();
image->pEnum = NULL;
}
void AddCueInfo( int idx )
/************************/
{
IEnumLINEINFO *pLines;
ULONG count;
jvm_line_info *cues;
LINEINFO curr_cue;
int i,j;
ImageEntry *image;
ULONG fetched;
AddModuleInfo( idx );
image = &ImageMap[idx];
if( image->cues_loaded ) return;
MustBeMainThread();
image->cues_loaded = TRUE;
image->num_cues = 0;
for( i = 0; i < image->num_methods; ++i ) {
pLines = NULL;
image->methods[i]->GetLineInfo( &pLines );
if( pLines == NULL ) continue;
pLines->GetCount( &count );
image->num_cues += count;
pLines->Release();
}
cues = image->cues = (jvm_line_info*)MSJAlloc( image->num_cues * sizeof( jvm_line_info ) );
for( i = 0; i < image->num_methods; ++i ) {
pLines = NULL;
image->methods[i]->GetLineInfo( &pLines );
if( pLines == NULL ) continue;
pLines->GetCount( &count );
for( j = 0; j < count; ++j ) {
pLines->Next( 1, &curr_cue, &fetched );
if( curr_cue.iLine == 0 ) {
image->num_cues--;
} else {
cues->offset = MAKE_OFFSET( idx, i, curr_cue.offPC );
cues->line = curr_cue.iLine;
++cues;
}
}
pLines->Release();
}
}
unsigned GetLibName( unsigned handle, char *name )
/************************************************/
{
int i;
for( i = 0; i < ImageMapTop; ++i ) {
if( ImageMap[i].newly_unloaded ) {
name[0] = '\0';
ImageMap[i].newly_unloaded = FALSE;
return( i+1 );
} else if( ImageMap[i].newly_loaded ) {
strcpy( name, ImageMap[i].className );
ImageMap[i].newly_loaded = FALSE;
LastNameGiven = i;
return( i+1 );
}
}
return( 0 );
}
void InitImageMap()
/*****************/
{
ImageEntry *image;
int i,j;
MustBeMainThread();
if( ImageMap != NULL ) {
image = ImageMap;
for( i = 0; i < ImageMapTop; ++i ) {
if( image->methods != NULL ) {
for( j = 0; j < image->num_methods; ++j ) {
image->methods[j]->Release();
}
MSJFree( image->methods );
}
if( image->cues ) MSJFree( image->cues );
++image;
}
MSJFree( ImageMap );
}
ImageMap = NULL;
ImageMapSize = 0;
ImageMapTop = 0;
}
extern addr48_off MakeMethodOffset( void *cls, void *meth, addr48_off offset )
/****************************************************************************/
{
int i,j;
for( i = 0; i < ImageMapTop; ++i ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -