- Enhanced internal variables framework (including read/save to

registry and typing)
- Finalized use of Windows' Console I/O interface (instead of Unix std
  streams)
- Now handling registers as internal variables (they are no longer
  seen as a specific type)
This commit is contained in:
Eric Pouech 2000-04-30 12:21:15 +00:00 committed by Alexandre Julliard
parent 8446ba04ab
commit 04c16b828e
19 changed files with 323 additions and 497 deletions

View File

@ -7,7 +7,6 @@
*/
#include "config.h"
#include <stdio.h>
#include "debugger.h"
#ifdef __i386__
@ -40,7 +39,7 @@
#define MAX_BREAKPOINTS 100
static BREAKPOINT breakpoints[MAX_BREAKPOINTS];
static DBG_BREAKPOINT breakpoints[MAX_BREAKPOINTS];
static int next_bp = 1; /* breakpoint 0 is reserved for step-over */

View File

@ -62,7 +62,6 @@
* Instruction disassembler.
*/
#include <stdio.h>
#include "debugger.h"
#ifdef __i386__

View File

@ -25,7 +25,6 @@ int curr_frame = 0;
static void issue_prompt(void);
static void mode_command(int);
void flush_symbols(void);
int yylex(void);
int yyerror(char *);
@ -34,7 +33,6 @@ int yyerror(char *);
%union
{
DBG_VALUE value;
enum debug_regs reg;
char * string;
int integer;
struct list_id listing;
@ -50,9 +48,8 @@ int yyerror(char *);
%token tFRAME tSHARE tCOND tDISPLAY tUNDISPLAY tDISASSEMBLE
%token tSTEPI tNEXTI tFINISH tSHOW tDIR tWHATIS
%token <string> tPATH
%token <string> tIDENTIFIER tSTRING tDEBUGSTR
%token <string> tIDENTIFIER tSTRING tDEBUGSTR tINTVAR
%token <integer> tNUM tFORMAT
%token <reg> tREG
%token tSYMBOLFILE
%token tCHAR tSHORT tINT tLONG tFLOAT tDOUBLE tUNSIGNED tSIGNED
@ -159,9 +156,7 @@ command:
| walk_command
set_command:
tSET tREG '=' expr_value tEOL { DEBUG_SetRegister( $2, $4 );
DEBUG_FreeExprMem(); }
| tSET lval_addr '=' expr_value tEOL { DEBUG_WriteMemory( &$2.addr, $4 );
tSET lval_addr '=' expr_value tEOL { DEBUG_WriteMemory( &$2, $4 );
DEBUG_FreeExprMem(); }
pathname:
@ -315,9 +310,8 @@ expr_addr:
expr_value:
expr { DBG_VALUE value = DEBUG_EvalExpr($1);
/* expr_value is typed as an integer */
if (!value.addr.off ||
!DEBUG_READ_MEM((void*)value.addr.off, &$$, sizeof($$)))
$$ = 0; }
$$ = DEBUG_ReadMemory(&value); }
/*
* The expr rule builds an expression tree. When we are done, we call
* EvalExpr to evaluate the value of the expression. The advantage of
@ -327,7 +321,7 @@ expr_value:
expr:
tNUM { $$ = DEBUG_ConstExpr($1); }
| tSTRING { $$ = DEBUG_StringExpr($1); }
| tREG { $$ = DEBUG_RegisterExpr($1); }
| tINTVAR { $$ = DEBUG_IntVarExpr($1); }
| tIDENTIFIER { $$ = DEBUG_SymbolExpr($1); }
| expr OP_DRF tIDENTIFIER { $$ = DEBUG_StructPExpr($1, $3); }
| expr '.' tIDENTIFIER { $$ = DEBUG_StructExpr($1, $3); }
@ -335,8 +329,8 @@ expr:
| tIDENTIFIER '(' expr ')' { $$ = DEBUG_CallExpr($1, 1, $3); }
| tIDENTIFIER '(' expr ',' expr ')' { $$ = DEBUG_CallExpr($1, 2, $3, $5); }
| tIDENTIFIER '(' expr ',' expr ',' expr ')' { $$ = DEBUG_CallExpr($1, 3, $3, $5, $7); }
| tIDENTIFIER '(' expr ',' expr ',' expr ',' expr ')' { $$ = DEBUG_CallExpr($1, 3, $3, $5, $7, $9); }
| tIDENTIFIER '(' expr ',' expr ',' expr ',' expr ',' expr ')' { $$ = DEBUG_CallExpr($1, 3, $3, $5, $7, $9, $11); }
| tIDENTIFIER '(' expr ',' expr ',' expr ',' expr ')' { $$ = DEBUG_CallExpr($1, 4, $3, $5, $7, $9); }
| tIDENTIFIER '(' expr ',' expr ',' expr ',' expr ',' expr ')' { $$ = DEBUG_CallExpr($1, 5, $3, $5, $7, $9, $11); }
| expr '[' expr ']' { $$ = DEBUG_BinopExpr(EXP_OP_ARR, $1, $3); }
| expr ':' expr { $$ = DEBUG_BinopExpr(EXP_OP_SEG, $1, $3); }
| expr OP_LOR expr { $$ = DEBUG_BinopExpr(EXP_OP_LOR, $1, $3); }
@ -379,7 +373,7 @@ lval:
lvalue:
tNUM { $$ = DEBUG_ConstExpr($1); }
| tREG { $$ = DEBUG_RegisterExpr($1); }
| tINTVAR { $$ = DEBUG_IntVarExpr($1); }
| tIDENTIFIER { $$ = DEBUG_SymbolExpr($1); }
| lvalue OP_DRF tIDENTIFIER { $$ = DEBUG_StructPExpr($1, $3); }
| lvalue '.' tIDENTIFIER { $$ = DEBUG_StructExpr($1, $3); }

View File

@ -5,7 +5,6 @@
*/
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "debugger.h"
@ -23,11 +22,8 @@
if ( (result = dbg_read((char *) buf, max_size )) < 0 ) \
YY_FATAL_ERROR( "read() in flex scanner failed" );
extern char * readline(const char *);
extern void add_history(char *);
static int dbg_read(char * buf, int size);
static char * make_symbol(char *);
void flush_symbols();
#endif /* DONT_USE_READLINE */
@ -86,33 +82,6 @@ STRING \"[^\n"]+\"
{STRING} { yylval.string = make_symbol(yytext); return tSTRING; }
<DEBUGSTR>[a-z+\-,]* { yylval.string = yytext; return tDEBUGSTR; }
$pc { yylval.reg = REG_EIP; return tREG; }
$flags { yylval.reg = REG_EFL; return tREG; }
$eip { yylval.reg = REG_EIP; return tREG; }
$ip { yylval.reg = REG_IP; return tREG; }
$esp { yylval.reg = REG_ESP; return tREG; }
$sp { yylval.reg = REG_SP; return tREG; }
$eax { yylval.reg = REG_EAX; return tREG; }
$ebx { yylval.reg = REG_EBX; return tREG; }
$ecx { yylval.reg = REG_ECX; return tREG; }
$edx { yylval.reg = REG_EDX; return tREG; }
$esi { yylval.reg = REG_ESI; return tREG; }
$edi { yylval.reg = REG_EDI; return tREG; }
$ebp { yylval.reg = REG_EBP; return tREG; }
$ax { yylval.reg = REG_AX; return tREG; }
$bx { yylval.reg = REG_BX; return tREG; }
$cx { yylval.reg = REG_CX; return tREG; }
$dx { yylval.reg = REG_DX; return tREG; }
$si { yylval.reg = REG_SI; return tREG; }
$di { yylval.reg = REG_DI; return tREG; }
$bp { yylval.reg = REG_BP; return tREG; }
$es { yylval.reg = REG_ES; return tREG; }
$ds { yylval.reg = REG_DS; return tREG; }
$cs { yylval.reg = REG_CS; return tREG; }
$ss { yylval.reg = REG_SS; return tREG; }
$fs { yylval.reg = REG_FS; return tREG; }
$gs { yylval.reg = REG_GS; return tREG; }
<INITIAL>info|inf|in { BEGIN(INFO_CMD); return tINFO; }
<INITIAL>up { BEGIN(NOCMD); return tUP; }
<INITIAL>down|dow|do { BEGIN(NOCMD); return tDOWN; }
@ -184,6 +153,7 @@ union { return tUNION; }
enum { return tENUM; }
{IDENTIFIER} { yylval.string = make_symbol(yytext); return tIDENTIFIER; }
"$"{IDENTIFIER} { yylval.string = make_symbol(yytext+1); return tINTVAR; }
<PATH_EXPECTED>{PATHNAME} { yylval.string = make_symbol(yytext); return tPATH; }
@ -279,11 +249,12 @@ static int dbg_read(char * buf, int size)
static char *local_symbols[30];
static int next_symbol;
char * make_symbol(char * symbol){
static char * make_symbol(char * symbol)
{
return local_symbols[next_symbol++] = DBG_strdup(symbol);
}
void flush_symbols()
void flush_symbols(void)
{
while(--next_symbol>= 0) DBG_free(local_symbols[next_symbol]);
next_symbol = 0;

View File

@ -41,6 +41,7 @@ enum debug_type {DT_BASIC, DT_CONST, DT_POINTER, DT_ARRAY, DT_STRUCT, DT_ENUM, D
/*
* For constants generated by the parser, we use this datatype
*/
extern struct datatype * DEBUG_TypeShortUInt;
extern struct datatype * DEBUG_TypeInt;
extern struct datatype * DEBUG_TypeIntConst;
extern struct datatype * DEBUG_TypeUSInt;
@ -135,7 +136,7 @@ typedef struct
} w;
} u;
struct expr * condition;
} BREAKPOINT;
} DBG_BREAKPOINT;
typedef struct tagDBG_THREAD {
struct tagDBG_PROCESS* process;
@ -147,7 +148,7 @@ typedef struct tagDBG_THREAD {
int dbg_mode;
enum exec_mode dbg_exec_mode;
int dbg_exec_count;
BREAKPOINT stepOverBP;
DBG_BREAKPOINT stepOverBP;
struct tagDBG_THREAD* next;
struct tagDBG_THREAD* prev;
} DBG_THREAD;
@ -207,20 +208,12 @@ typedef struct tagDBG_MODULE {
#define DM_TYPE_NE 2
#define DM_TYPE_PE 3
#ifdef __i386__
#ifdef REG_SP /* Some Sun includes define this */
#undef REG_SP
#endif
enum debug_regs
{
REG_EAX, REG_EBX, REG_ECX, REG_EDX, REG_ESI,
REG_EDI, REG_EBP, REG_EFL, REG_EIP, REG_ESP,
REG_AX, REG_BX, REG_CX, REG_DX, REG_SI,
REG_DI, REG_BP, REG_FL, REG_IP, REG_SP,
REG_CS, REG_DS, REG_ES, REG_SS, REG_FS, REG_GS
};
#endif
typedef struct {
DWORD val;
const char* name;
LPDWORD pval;
struct datatype* type;
} DBG_INTVAR;
#define OFFSET_OF(__c,__f) ((int)(((char*)&(((__c*)0)->__f))-((char*)0)))
@ -241,9 +234,27 @@ extern int DEBUG_AddBPCondition(int bpnum, struct expr * exp);
/* debugger/db_disasm.c */
extern void DEBUG_Disasm( DBG_ADDR *addr, int display );
/* debugger/dbg.y */
extern BOOL DEBUG_Main( BOOL is_debug, BOOL force, DWORD code );
extern void DEBUG_Exit( DWORD );
/* debugger/debug.l */
extern void flush_symbols(void);
/* debugger/display.c */
extern int DEBUG_DoDisplay(void);
extern int DEBUG_AddDisplay(struct expr * exp, int count, char format);
extern int DEBUG_DoDisplay(void);
extern int DEBUG_DelDisplay(int displaynum);
extern int DEBUG_InfoDisplay(void);
/* debugger/editline.c */
extern char * readline(const char *);
extern void add_history(char *);
/* debugger/expr.c */
extern void DEBUG_FreeExprMem(void);
struct expr * DEBUG_RegisterExpr(enum debug_regs);
struct expr * DEBUG_IntVarExpr(const char* name);
struct expr * DEBUG_SymbolExpr(const char * name);
struct expr * DEBUG_ConstExpr(int val);
struct expr * DEBUG_StringExpr(const char * str);
@ -262,12 +273,8 @@ extern struct expr * DEBUG_CloneExpr(const struct expr * exp);
extern int DEBUG_FreeExpr(struct expr * exp);
extern int DEBUG_DisplayExpr(const struct expr * exp);
/* debugger/display.c */
extern int DEBUG_DoDisplay(void);
extern int DEBUG_AddDisplay(struct expr * exp, int count, char format);
extern int DEBUG_DoDisplay(void);
extern int DEBUG_DelDisplay(int displaynum);
extern int DEBUG_InfoDisplay(void);
/* debugger/external.c */
extern void DEBUG_ExternalDebugger(void);
/* debugger/hash.c */
extern struct name_hash * DEBUG_AddSymbol( const char *name,
@ -329,8 +336,8 @@ extern void DEBUG_InfoWindow(HWND hWnd);
extern void DEBUG_WalkWindows(HWND hWnd, int indent);
/* debugger/memory.c */
extern int DEBUG_ReadMemory( const DBG_ADDR *address );
extern void DEBUG_WriteMemory( const DBG_ADDR *address, int value );
extern int DEBUG_ReadMemory( const DBG_VALUE* value );
extern void DEBUG_WriteMemory( const DBG_VALUE* val, int value );
extern void DEBUG_ExamineMemory( const DBG_VALUE *addr, int count, char format);
extern void DEBUG_InvalAddr( const DBG_ADDR* addr );
extern void DEBUG_InvalLinAddr( void* addr );
@ -360,11 +367,8 @@ extern int DEBUG_RegisterStabsDebugInfo(DBG_MODULE* module, HANDLE hFile, void*
extern void DEBUG_InitCVDataTypes(void);
/* debugger/registers.c */
extern void DEBUG_SetRegister( enum debug_regs reg, int val );
extern int DEBUG_GetRegister( enum debug_regs reg );
extern void DEBUG_InfoRegisters(void);
extern BOOL DEBUG_ValidateRegisters(void);
extern int DEBUG_PrintRegister(enum debug_regs reg);
/* debugger/stack.c */
extern void DEBUG_InfoStack(void);
@ -418,20 +422,15 @@ extern void DEBUG_List(struct list_id * line1, struct list_id * line2,
extern void DEBUG_NukePath(void);
extern void DEBUG_Disassemble( const DBG_VALUE *, const DBG_VALUE*, int offset );
/* debugger/external.c */
extern void DEBUG_ExternalDebugger(void);
/* debugger/dbg.y */
extern BOOL DEBUG_Main( BOOL is_debug, BOOL force, DWORD code );
extern void DEBUG_Exit( DWORD );
/* debugger/winedbg.c */
#define DBG_CHN_MESG 1
#define DBG_CHN_ERR 2
#define DBG_CHN_WARN 4
#define DBG_CHN_FIXME 8
#define DBG_CHN_TRACE 16
extern void DEBUG_Output(int chn, const char* buffer, int len);
extern int DEBUG_Printf(int chn, const char* format, ...);
extern DBG_INTVAR* DEBUG_GetIntVar(const char*);
/* Choose your allocator! */
#if 1
@ -465,9 +464,16 @@ extern HANDLE dbg_heap;
#define DEBUG_STATUS_DIV_BY_ZERO (DEBUG_STATUS_OFFSET+2)
#define DEBUG_STATUS_BAD_TYPE (DEBUG_STATUS_OFFSET+3)
#define DBG_IVAR(_var) DEBUG_IV_##_var
#define INTERNAL_VAR(_var,_val) extern int DBG_IVAR(_var);
extern DBG_INTVAR DEBUG_IntVars[];
#define DBG_IVARNAME(_var) DEBUG_IV_##_var
#define DBG_IVARSTRUCT(_var) DEBUG_IntVars[DBG_IVARNAME(_var)]
#define DBG_IVAR(_var) (*(DBG_IVARSTRUCT(_var).pval))
#define INTERNAL_VAR(_var,_val,_ref,_typ) DBG_IVARNAME(_var),
enum debug_int_var {
#include "intvar.h"
DBG_IV_LAST
};
#undef INTERNAL_VAR
#endif /* __WINE_DEBUGGER_H */

View File

@ -6,7 +6,6 @@
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <sys/types.h>

View File

@ -27,12 +27,7 @@
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "windef.h"
#include "debugger.h"
@ -136,94 +131,29 @@ int rl_meta_chars = 1;
** Declarations.
*/
static CHAR *editinput();
extern int read();
extern int write();
#if defined(USE_TERMCAP)
extern char *getenv();
extern char *tgetstr();
extern int tgetent();
#endif /* defined(USE_TERMCAP) */
/*
** TTY input/output functions.
*/
#ifdef HAVE_TCGETATTR
#include <termios.h>
static void
rl_ttyset(int Reset)
{
static struct termios old;
struct termios new;
static DWORD old_mode;
if (Reset == 0) {
(void)tcgetattr(0, &old);
rl_erase = old.c_cc[VERASE];
rl_kill = old.c_cc[VKILL];
rl_eof = old.c_cc[VEOF];
rl_intr = old.c_cc[VINTR];
rl_quit = old.c_cc[VQUIT];
new = old;
new.c_cc[VINTR] = -1;
new.c_cc[VQUIT] = -1;
new.c_lflag &= ~(ECHO | ICANON);
new.c_iflag &= ~(ISTRIP | INPCK);
new.c_cc[VMIN] = 1;
new.c_cc[VTIME] = 0;
(void)tcsetattr(0, TCSANOW, &new);
}
else
(void)tcsetattr(0, TCSANOW, &old);
}
#else /* HAVE_TCGETATTR */
static void
rl_ttyset(int Reset)
{
static struct sgttyb old_sgttyb;
static struct tchars old_tchars;
struct sgttyb new_sgttyb;
struct tchars new_tchars;
if (Reset == 0) {
(void)ioctl(0, TIOCGETP, &old_sgttyb);
rl_erase = old_sgttyb.sg_erase;
rl_kill = old_sgttyb.sg_kill;
(void)ioctl(0, TIOCGETC, &old_tchars);
rl_eof = old_tchars.t_eofc;
rl_intr = old_tchars.t_intrc;
rl_quit = old_tchars.t_quitc;
new_sgttyb = old_sgttyb;
new_sgttyb.sg_flags &= ~ECHO;
new_sgttyb.sg_flags |= RAW;
#if defined(PASS8)
new_sgttyb.sg_flags |= PASS8;
#endif /* defined(PASS8) */
(void)ioctl(0, TIOCSETP, &new_sgttyb);
new_tchars = old_tchars;
new_tchars.t_intrc = -1;
new_tchars.t_quitc = -1;
(void)ioctl(0, TIOCSETC, &new_tchars);
}
else {
(void)ioctl(0, TIOCSETP, &old_sgttyb);
(void)ioctl(0, TIOCSETC, &old_tchars);
GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &old_mode);
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), 0 /*ENABLE_PROCESSED_INPUT|ENABLE_WINDOW_INPUT|ENABLE_MOUSE_INPUT*/);
} else {
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), old_mode);
}
}
#endif /* HAVE_TCGETATTR */
static void
TTYflush(void)
{
if (ScreenCount) {
(void)write(1, Screen, ScreenCount);
DEBUG_Output(DBG_CHN_MESG, Screen, ScreenCount);
ScreenCount = 0;
}
}
@ -276,7 +206,7 @@ static unsigned int
TTYget(void)
{
CHAR c;
int retv;
DWORD retv;
TTYflush();
if (Pushed) {
@ -286,16 +216,22 @@ TTYget(void)
if (*Input)
return *Input++;
while ( ( retv = read( 0, &c, (size_t)1 ) ) == -1 )
{
if ( errno != EINTR )
{
perror( "read" );
for (;;) {
/* data available ? */
if (ReadConsole(GetStdHandle(STD_INPUT_HANDLE), &c, 1, &retv, NULL) &&
retv == 1)
return c;
switch (WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), INFINITE)) {
case WAIT_OBJECT_0:
break;
default:
DEBUG_Printf(DBG_CHN_FIXME, "shouldn't happen\n");
/* fall thru */
case WAIT_ABANDONED:
case WAIT_TIMEOUT:
return EOF;
}
}
return retv == 1 ? c : EOF;
}
#define TTYback() (backspace ? TTYputs((CHAR *)backspace) : TTYput('\b'))
@ -310,55 +246,9 @@ TTYbackn(int n)
static void
TTYinfo(void)
{
static int init;
#if defined(USE_TERMCAP)
char *term;
char buff[2048];
char *bp;
#endif /* defined(USE_TERMCAP) */
#if defined(TIOCGWINSZ)
struct winsize W;
#endif /* defined(TIOCGWINSZ) */
if (init) {
#if defined(TIOCGWINSZ)
/* Perhaps we got resized. */
if (ioctl(0, TIOCGWINSZ, &W) >= 0
&& W.ws_col > 0 && W.ws_row > 0) {
TTYwidth = (int)W.ws_col;
TTYrows = (int)W.ws_row;
}
#endif /* defined(TIOCGWINSZ) */
return;
}
init++;
TTYwidth = TTYrows = 0;
#if defined(USE_TERMCAP)
bp = &buff[0];
if ((term = getenv("TERM")) == NULL)
term = "dumb";
if (tgetent(buff, term) < 0) {
TTYwidth = SCREEN_WIDTH;
TTYrows = SCREEN_ROWS;
return;
}
backspace = tgetstr("le", &bp);
TTYwidth = tgetnum("co");
TTYrows = tgetnum("li");
#endif /* defined(USE_TERMCAP) */
#if defined(TIOCGWINSZ)
if (ioctl(0, TIOCGWINSZ, &W) >= 0) {
TTYwidth = (int)W.ws_col;
TTYrows = (int)W.ws_row;
}
#endif /* defined(TIOCGWINSZ) */
if (TTYwidth <= 0 || TTYrows <= 0) {
TTYwidth = SCREEN_WIDTH;
TTYrows = SCREEN_ROWS;
}
COORD c = GetLargestConsoleWindowSize(GetStdHandle(STD_INPUT_HANDLE));
TTYwidth = c.x;
TTYrows = c.y;
}

View File

@ -7,7 +7,6 @@
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "winbase.h"
#include "wine/winbase16.h"
@ -45,9 +44,8 @@ struct expr
struct
{
enum debug_regs reg;
int result;
} rgister;
const char * name;
} intvar;
struct
{
@ -97,7 +95,7 @@ struct expr
#define EXPR_TYPE_CONST 0
#define EXPR_TYPE_US_CONST 1
#define EXPR_TYPE_SYMBOL 2
#define EXPR_TYPE_REGISTER 3
#define EXPR_TYPE_INTVAR 3
#define EXPR_TYPE_BINOP 4
#define EXPR_TYPE_UNOP 5
#define EXPR_TYPE_STRUCT 6
@ -151,14 +149,14 @@ DEBUG_TypeCastExpr(struct datatype * dt, struct expr * exp)
}
struct expr *
DEBUG_RegisterExpr(enum debug_regs regno)
DEBUG_IntVarExpr(const char* name)
{
struct expr * ex;
ex = DEBUG_GetFreeExpr();
ex->type = EXPR_TYPE_REGISTER;
ex->un.rgister.reg = regno;
ex->type = EXPR_TYPE_INTVAR;
ex->un.intvar.name = name;
return ex;
}
@ -429,18 +427,17 @@ DBG_VALUE DEBUG_EvalExpr(struct expr * exp)
rtn.addr.off = (unsigned int) &exp->un.call.result;
break;
case EXPR_TYPE_REGISTER:
rtn.type = DEBUG_TypeIntConst;
case EXPR_TYPE_INTVAR:
{
DBG_INTVAR* div = DEBUG_GetIntVar(exp->un.intvar.name);
if (!div) RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
rtn.cookie = DV_HOST;
exp->un.rgister.result = DEBUG_GetRegister(exp->un.rgister.reg);
rtn.addr.off = (unsigned int) &exp->un.rgister.result;
#ifdef __i386__
if( exp->un.rgister.reg == REG_EIP )
rtn.addr.seg = DEBUG_context.SegCs;
else
rtn.addr.seg = DEBUG_context.SegDs;
#endif
DEBUG_FixAddress( &rtn.addr, 0 );
rtn.type = div->type;
rtn.addr.off = (unsigned int)div->pval;
/* EPP FIXME rtn.addr.seg = ?? */
}
break;
case EXPR_TYPE_BINOP:
exp1 = DEBUG_EvalExpr(exp->un.binop.exp1);
@ -662,8 +659,8 @@ DEBUG_DisplayExpr(const struct expr * exp)
DEBUG_DisplayExpr(exp->un.cast.expr);
DEBUG_Printf(DBG_CHN_MESG, ")");
break;
case EXPR_TYPE_REGISTER:
DEBUG_PrintRegister(exp->un.rgister.reg);
case EXPR_TYPE_INTVAR:
DEBUG_Printf(DBG_CHN_MESG, "$%s", exp->un.intvar.name);
break;
case EXPR_TYPE_US_CONST:
DEBUG_Printf(DBG_CHN_MESG, "%ud", exp->un.u_const.value);
@ -821,7 +818,9 @@ DEBUG_CloneExpr(const struct expr * exp)
case EXPR_TYPE_CAST:
rtn->un.cast.expr = DEBUG_CloneExpr(exp->un.cast.expr);
break;
case EXPR_TYPE_REGISTER:
case EXPR_TYPE_INTVAR:
rtn->un.intvar.name = DBG_strdup(exp->un.intvar.name);
break;
case EXPR_TYPE_US_CONST:
case EXPR_TYPE_CONST:
break;
@ -874,7 +873,9 @@ DEBUG_FreeExpr(struct expr * exp)
case EXPR_TYPE_CAST:
DEBUG_FreeExpr(exp->un.cast.expr);
break;
case EXPR_TYPE_REGISTER:
case EXPR_TYPE_INTVAR:
DBG_free((char *) exp->un.intvar.name);
break;
case EXPR_TYPE_US_CONST:
case EXPR_TYPE_CONST:
break;

View File

@ -1138,6 +1138,7 @@ BOOL DEBUG_GetStackSymbolValue( const char * name, DBG_VALUE *value )
/*
* Register variable. Point to DEBUG_context field.
*/
assert(curr_func->local_vars[i].regno - 1 < sizeof(reg_ofs)/sizeof(reg_ofs[0]));
value->addr.off = ((DWORD)&DEBUG_context) +
reg_ofs[curr_func->local_vars[i].regno - 1];
value->cookie = DV_HOST;

View File

@ -6,7 +6,6 @@
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "winbase.h"
@ -92,22 +91,21 @@ void DEBUG_PrintBasic( const DBG_VALUE* value, int count, char format )
char* str = (char*)(long)res;
for (; DEBUG_READ_MEM(str, &ch, 1) && ch; str++) {
fputc(ch, stderr);
DEBUG_Output(DBG_CHN_MESG, &ch, 1);
DEBUG_nchar++;
}
}
else
{
/* shouldn't happen */
fputc('%', stderr);
fputc(*ptr, stderr);
DEBUG_Printf(DBG_CHN_MESG, "%%%c", *ptr);
DEBUG_nchar += 2;
}
state = 0;
}
else
{
fputc(*ptr, stderr);
DEBUG_Output(DBG_CHN_MESG, ptr, 1);
DEBUG_nchar++;
}
}

View File

@ -1,3 +1,51 @@
INTERNAL_VAR(BreakAllThreadsStartup, FALSE)
INTERNAL_VAR(ExtDbgOnInvalidAddress, FALSE)
INTERNAL_VAR(ChannelMask, DBG_CHN_MESG)
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
/* Wine internal debugger
* Definitionz for internal variables
* Eric Pouech (c) 2000
*/
/* break handling */
INTERNAL_VAR(BreakAllThreadsStartup, FALSE, NULL, DEBUG_TypeIntConst)
INTERNAL_VAR(BreakOnCritSectTimeOut, FALSE, NULL, DEBUG_TypeIntConst)
/* output handling */
INTERNAL_VAR(ConChannelMask, DBG_CHN_MESG, NULL, DEBUG_TypeIntConst)
INTERNAL_VAR(StdChannelMask, 0, NULL, DEBUG_TypeIntConst)
INTERNAL_VAR(UseXTerm, TRUE, NULL, DEBUG_TypeIntConst)
/* debugging debugger */
INTERNAL_VAR(ExtDbgOnInvalidAddress, FALSE, NULL, DEBUG_TypeIntConst)
/* context manipulation */
#ifdef __i386__
/* FIXME: 16 bit registers use imply that CPU is little endian, which is
* the case when running natively i386 code
*/
INTERNAL_VAR(eip, 0, &DEBUG_context.Eip, DEBUG_TypeIntConst)
INTERNAL_VAR(ip, 0, &DEBUG_context.Eip, DEBUG_TypeShortUInt)
INTERNAL_VAR(pc, 0, &DEBUG_context.Eip, DEBUG_TypeIntConst)
INTERNAL_VAR(flags, 0, &DEBUG_context.EFlags, DEBUG_TypeIntConst)
INTERNAL_VAR(esp, 0, &DEBUG_context.Esp, DEBUG_TypeIntConst)
INTERNAL_VAR(sp, 0, &DEBUG_context.Esp, DEBUG_TypeShortUInt)
INTERNAL_VAR(eax, 0, &DEBUG_context.Eax, DEBUG_TypeIntConst)
INTERNAL_VAR(ax, 0, &DEBUG_context.Eax, DEBUG_TypeShortUInt)
INTERNAL_VAR(ebx, 0, &DEBUG_context.Ebx, DEBUG_TypeIntConst)
INTERNAL_VAR(bx, 0, &DEBUG_context.Ebx, DEBUG_TypeShortUInt)
INTERNAL_VAR(ecx, 0, &DEBUG_context.Ecx, DEBUG_TypeIntConst)
INTERNAL_VAR(cx, 0, &DEBUG_context.Ecx, DEBUG_TypeShortUInt)
INTERNAL_VAR(edx, 0, &DEBUG_context.Edx, DEBUG_TypeIntConst)
INTERNAL_VAR(dx, 0, &DEBUG_context.Edx, DEBUG_TypeShortUInt)
INTERNAL_VAR(esi, 0, &DEBUG_context.Esi, DEBUG_TypeIntConst)
INTERNAL_VAR(si, 0, &DEBUG_context.Esi, DEBUG_TypeShortUInt)
INTERNAL_VAR(edi, 0, &DEBUG_context.Edi, DEBUG_TypeIntConst)
INTERNAL_VAR(di, 0, &DEBUG_context.Edi, DEBUG_TypeShortUInt)
INTERNAL_VAR(ebp, 0, &DEBUG_context.Ebp, DEBUG_TypeIntConst)
INTERNAL_VAR(bp, 0, &DEBUG_context.Ebp, DEBUG_TypeShortUInt)
INTERNAL_VAR(es, 0, &DEBUG_context.SegEs, DEBUG_TypeIntConst)
INTERNAL_VAR(ds, 0, &DEBUG_context.SegDs, DEBUG_TypeIntConst)
INTERNAL_VAR(cs, 0, &DEBUG_context.SegCs, DEBUG_TypeIntConst)
INTERNAL_VAR(ss, 0, &DEBUG_context.SegSs, DEBUG_TypeIntConst)
INTERNAL_VAR(fs, 0, &DEBUG_context.SegFs, DEBUG_TypeIntConst)
INTERNAL_VAR(gs, 0, &DEBUG_context.SegGs, DEBUG_TypeIntConst)
#endif

View File

@ -7,7 +7,6 @@
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -140,16 +139,30 @@ void DEBUG_InvalLinAddr( void* addr )
*
* Read a memory value.
*/
int DEBUG_ReadMemory( const DBG_ADDR *address )
/* FIXME: this function is now getting closer and closer to
* DEBUG_ExprGetValue. They should be merged...
*/
int DEBUG_ReadMemory( const DBG_VALUE* val )
{
DBG_ADDR addr = *address;
int value = 0; /* to clear any unused byte */
int os = DEBUG_GetObjectSize(val->type);
assert(sizeof(value) >= os);
/* FIXME: only works on little endian systems */
if (val->cookie == DV_TARGET) {
DBG_ADDR addr = val->addr;
void* lin;
int value;
DEBUG_FixAddress( &addr, DEBUG_context.SegDs );
lin = (void*)DEBUG_ToLinear( &addr );
if (!DEBUG_READ_MEM_VERBOSE(lin, &value, sizeof(value)))
value = 0;
DEBUG_READ_MEM_VERBOSE(lin, &value, os);
} else {
if (val->addr.off)
memcpy(&value, (void*)val->addr.off, os);
}
return value;
}
@ -159,14 +172,24 @@ int DEBUG_ReadMemory( const DBG_ADDR *address )
*
* Store a value in memory.
*/
void DEBUG_WriteMemory( const DBG_ADDR *address, int value )
void DEBUG_WriteMemory( const DBG_VALUE* val, int value )
{
DBG_ADDR addr = *address;
int os = DEBUG_GetObjectSize(val->type);
assert(sizeof(value) >= os);
/* FIXME: only works on little endian systems */
if (val->cookie == DV_TARGET) {
DBG_ADDR addr = val->addr;
void* lin;
DEBUG_FixAddress( &addr, DEBUG_context.SegDs );
lin = (void*)DEBUG_ToLinear( &addr );
DEBUG_WRITE_MEM_VERBOSE(lin, &value, sizeof(value));
DEBUG_WRITE_MEM_VERBOSE(lin, &value, os);
} else {
memcpy((void*)val->addr.off, &value, os);
}
}
@ -242,7 +265,7 @@ void DEBUG_ExamineMemory( const DBG_VALUE *_value, int count, char format )
if (!DEBUG_READ_MEM_VERBOSE(pnt, &wch, sizeof(wch)))
break;
pnt += sizeof(wch);
fputc( (char)wch, stderr );
DEBUG_Printf(DBG_CHN_MESG, "%c", (char)wch);
}
DEBUG_Printf(DBG_CHN_MESG,"\n");
return;
@ -256,7 +279,7 @@ void DEBUG_ExamineMemory( const DBG_VALUE *_value, int count, char format )
if (!DEBUG_READ_MEM_VERBOSE(pnt, &ch, sizeof(ch)))
break;
pnt++;
fputc( ch, stderr );
DEBUG_Output(DBG_CHN_MESG, &ch, 1);
}
DEBUG_Printf(DBG_CHN_MESG,"\n");
return;

View File

@ -5,135 +5,9 @@
*/
#include "config.h"
#include <stdio.h>
#include <string.h>
#include "debugger.h"
/***********************************************************************
* DEBUG_SetRegister
*
* Set a register value.
*/
void DEBUG_SetRegister( enum debug_regs reg, int val )
{
#ifdef __i386__
switch(reg)
{
case REG_EAX: DEBUG_context.Eax = val; break;
case REG_EBX: DEBUG_context.Ebx = val; break;
case REG_ECX: DEBUG_context.Ecx = val; break;
case REG_EDX: DEBUG_context.Edx = val; break;
case REG_ESI: DEBUG_context.Esi = val; break;
case REG_EDI: DEBUG_context.Edi = val; break;
case REG_EBP: DEBUG_context.Ebp = val; break;
case REG_EFL: DEBUG_context.EFlags = val; break;
case REG_EIP: DEBUG_context.Eip = val; break;
case REG_ESP: DEBUG_context.Esp = val; break;
case REG_CS: DEBUG_context.SegCs = val; break;
case REG_DS: DEBUG_context.SegDs = val; break;
case REG_ES: DEBUG_context.SegEs = val; break;
case REG_SS: DEBUG_context.SegSs = val; break;
case REG_FS: DEBUG_context.SegFs = val; break;
case REG_GS: DEBUG_context.SegGs = val; break;
#define SET_LOW_WORD(dw,lw) ((dw) = ((dw) & 0xFFFF0000) | LOWORD(lw))
case REG_AX: SET_LOW_WORD(DEBUG_context.Eax,val); break;
case REG_BX: SET_LOW_WORD(DEBUG_context.Ebx,val); break;
case REG_CX: SET_LOW_WORD(DEBUG_context.Ecx,val); break;
case REG_DX: SET_LOW_WORD(DEBUG_context.Edx,val); break;
case REG_SI: SET_LOW_WORD(DEBUG_context.Esi,val); break;
case REG_DI: SET_LOW_WORD(DEBUG_context.Edi,val); break;
case REG_BP: SET_LOW_WORD(DEBUG_context.Ebp,val); break;
case REG_FL: SET_LOW_WORD(DEBUG_context.EFlags,val); break;
case REG_IP: SET_LOW_WORD(DEBUG_context.Eip,val); break;
case REG_SP: SET_LOW_WORD(DEBUG_context.Esp,val); break;
#undef SET_LOWORD
}
#endif
}
int DEBUG_PrintRegister(enum debug_regs reg)
{
#ifdef __i386__
char* val = NULL;
switch(reg)
{
case REG_EAX: val = "%%eax"; break;
case REG_EBX: val = "%%ebx"; break;
case REG_ECX: val = "%%ecx"; break;
case REG_EDX: val = "%%edx"; break;
case REG_ESI: val = "%%esi"; break;
case REG_EDI: val = "%%edi"; break;
case REG_EBP: val = "%%ebp"; break;
case REG_EFL: val = "%%efl"; break;
case REG_EIP: val = "%%eip"; break;
case REG_ESP: val = "%%esp"; break;
case REG_AX: val = "%%ax"; break;
case REG_BX: val = "%%bx"; break;
case REG_CX: val = "%%cx"; break;
case REG_DX: val = "%%dx"; break;
case REG_SI: val = "%%si"; break;
case REG_DI: val = "%%di"; break;
case REG_BP: val = "%%bp"; break;
case REG_FL: val = "%%fl"; break;
case REG_IP: val = "%%ip"; break;
case REG_SP: val = "%%sp"; break;
case REG_CS: val = "%%cs"; break;
case REG_DS: val = "%%ds"; break;
case REG_ES: val = "%%es"; break;
case REG_SS: val = "%%ss"; break;
case REG_FS: val = "%%fs"; break;
case REG_GS: val = "%%gs"; break;
}
if (val) DEBUG_Printf(DBG_CHN_MESG, val);
return TRUE;
#else
return FALSE;
#endif
}
/***********************************************************************
* DEBUG_GetRegister
*
* Get a register value.
*/
int DEBUG_GetRegister( enum debug_regs reg )
{
#ifdef __i386__
switch(reg)
{
case REG_EAX: return DEBUG_context.Eax;
case REG_EBX: return DEBUG_context.Ebx;
case REG_ECX: return DEBUG_context.Ecx;
case REG_EDX: return DEBUG_context.Edx;
case REG_ESI: return DEBUG_context.Esi;
case REG_EDI: return DEBUG_context.Edi;
case REG_EBP: return DEBUG_context.Ebp;
case REG_EFL: return DEBUG_context.EFlags;
case REG_EIP: return DEBUG_context.Eip;
case REG_ESP: return DEBUG_context.Esp;
case REG_CS: return DEBUG_context.SegCs;
case REG_DS: return DEBUG_context.SegDs;
case REG_ES: return DEBUG_context.SegEs;
case REG_SS: return DEBUG_context.SegSs;
case REG_FS: return DEBUG_context.SegFs;
case REG_GS: return DEBUG_context.SegGs;
case REG_AX: return LOWORD(DEBUG_context.Eax);
case REG_BX: return LOWORD(DEBUG_context.Ebx);
case REG_CX: return LOWORD(DEBUG_context.Ecx);
case REG_DX: return LOWORD(DEBUG_context.Edx);
case REG_SI: return LOWORD(DEBUG_context.Esi);
case REG_DI: return LOWORD(DEBUG_context.Edi);
case REG_BP: return LOWORD(DEBUG_context.Ebp);
case REG_FL: return LOWORD(DEBUG_context.EFlags);
case REG_IP: return LOWORD(DEBUG_context.Eip);
case REG_SP: return LOWORD(DEBUG_context.Esp);
}
#endif
return 0; /* should not happen */
}
/***********************************************************************
* DEBUG_Flags
*
@ -141,6 +15,7 @@ int DEBUG_GetRegister( enum debug_regs reg )
*/
char *DEBUG_Flags( DWORD flag, char *buf )
{
#ifdef __i386__
char *pt;
strcpy( buf, " - 00 - - - " );
@ -185,6 +60,10 @@ char *DEBUG_Flags( DWORD flag, char *buf )
if ( flag & 0x00040000 ) *pt = 'a'; /* Alignment Check Flag */
if ( buf >= pt-- ) return( buf );
return( buf );
#else
strcpy(buf, "unknown CPU");
return buf;
#endif
}

View File

@ -183,11 +183,12 @@ DEBUG_DisplaySource(char * sourcefile, int start, int end)
if( sl == NULL )
{
char zbuf[256];
/*
* Still couldn't find it. Ask user for path to add.
*/
DEBUG_Printf(DBG_CHN_MESG,"Enter path to file %s: ", sourcefile);
fgets(tmppath, sizeof(tmppath), stdin);
sprintf(zbuf, "Enter path to file %s: ", sourcefile);
lstrcpynA(tmppath, readline(zbuf), sizeof(tmppath));
if( tmppath[strlen(tmppath)-1] == '\n' )
{

View File

@ -16,7 +16,6 @@
#include <sys/mman.h>
#endif
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@ -1318,17 +1317,14 @@ DEBUG_ReadExecutableDbgInfo(const char* exe_name)
/*
* Make sure we can stat and open this file.
*/
if( exe_name == NULL )
goto leave;
fprintf( stderr, "Loading symbols: %s", exe_name );
if (exe_name == NULL) goto leave;
DEBUG_ProcessElfObject(exe_name, 0);
/* previous step should have loaded symbol _DYNAMIC if it exists inside
* the main executable
*/
if (!DEBUG_GetSymbolValue("_DYNAMIC", -1, &val, FALSE)) {
fprintf(stderr, "Can't find symbol _DYNAMIC\n");
DEBUG_Printf(DBG_CHN_WARN, "Can't find symbol _DYNAMIC\n");
goto leave;
}
@ -1380,7 +1376,7 @@ DEBUG_ProcessElfObject(const char * filename, unsigned int load_offset)
}
int
DEBUG_ReadExecutableDbgInfo(void)
DEBUG_ReadExecutableDbgInfo(const char* exe_name)
{
return FALSE;
}

View File

@ -8,7 +8,6 @@
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include "debugger.h"

View File

@ -8,7 +8,6 @@
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
@ -113,7 +112,7 @@ struct datatype * DEBUG_TypeInt = NULL;
struct datatype * DEBUG_TypeIntConst = NULL;
struct datatype * DEBUG_TypeUSInt = NULL;
struct datatype * DEBUG_TypeString = NULL;
struct datatype * DEBUG_TypeShortUInt = NULL;
/*
* All of the types that have been defined so far.
*/
@ -319,7 +318,7 @@ DEBUG_InitTypes(void)
DEBUG_InitBasic(BASIC_LONGLONG,"long long int",8,1,"%ld");
DEBUG_InitBasic(BASIC_ULONGLONGI,"long long unsigned int",8,0,"%ld");
DEBUG_InitBasic(BASIC_SHORT,"short int",2,1,"%d");
DEBUG_InitBasic(BASIC_SHORTUI,"short unsigned int",2,0,"%d");
DEBUG_TypeShortUInt = DEBUG_InitBasic(BASIC_SHORTUI,"short unsigned int",2,0,"%d");
DEBUG_InitBasic(BASIC_SCHAR,"signed char",1,1,"'%c'");
DEBUG_InitBasic(BASIC_UCHAR,"unsigned char",1,0,"'%c'");
DEBUG_InitBasic(BASIC_FLT,"float",4,0,"%f");
@ -865,7 +864,7 @@ DEBUG_Print( const DBG_VALUE *value, int count, char format, int level )
DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "\"");
for( i=value->type->un.array.start; i < value->type->un.array.end; i++ )
{
fputc(*pnt++, stderr);
DEBUG_Output(DBG_CHN_MESG, pnt++, 1);
DEBUG_nchar++;
if( DEBUG_nchar > DEBUG_maxchar )
{

View File

@ -26,48 +26,81 @@ DBG_THREAD* DEBUG_CurrThread = NULL;
CONTEXT DEBUG_context;
static DBG_PROCESS* proc = NULL;
DBG_INTVAR DEBUG_IntVars[DBG_IV_LAST];
/* build internal vars table */
#define INTERNAL_VAR(_var,_val) int DBG_IVAR(_var) = _val;
#include "intvar.h"
#undef INTERNAL_VAR
void DEBUG_Output(int chn, const char* buffer, int len)
{
if (DBG_IVAR(ConChannelMask) & chn)
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buffer, len, NULL, NULL);
if (DBG_IVAR(StdChannelMask) & chn)
fwrite(buffer, len, 1, stderr);
}
int DEBUG_Printf(int chn, const char* format, ...)
{
char buf[1024];
va_list valist;
int len;
va_start(valist, format);
vsprintf(buf, format, valist);
len = vsprintf(buf, format, valist);
va_end(valist);
#if 0
if (DBG_IVAR(ChannelMask) & chn)
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, strlen(buf), NULL, NULL);
if (chn == DBG_CHN_MESG) fwrite(buf, strlen(buf), 1, stderr);
#else
if (DBG_IVAR(ChannelMask) & chn) fwrite(buf, strlen(buf), 1, stderr);
#endif
return strlen(buf);
DEBUG_Output(chn, buf, len);
return len;
}
static BOOL DEBUG_Init(void)
static BOOL DEBUG_IntVarsRW(int read)
{
HKEY hkey;
DWORD type;
DWORD type = REG_DWORD;
DWORD val;
DWORD count = sizeof(val);
int i;
DBG_INTVAR* div = DEBUG_IntVars;
if (!RegOpenKey(HKEY_CURRENT_USER, "Software\\Wine\\WineDbg", &hkey)) {
#define INTERNAL_VAR(_var,_val) \
if (!RegQueryValueEx(hkey, #_var, 0, &type, (LPSTR)&val, &count)) \
DBG_IVAR(_var) = val;
if (read) {
/* initializes internal vars table */
#define INTERNAL_VAR(_var,_val,_ref,_typ) \
div->val = _val; div->name = #_var; div->pval = _ref; \
div->type = _typ; div++;
#include "intvar.h"
#undef INTERNAL_VAR
}
if (!RegOpenKey(HKEY_CURRENT_USER, "Software\\Wine\\WineDbg", &hkey)) {
for (i = 0; i < DBG_IV_LAST; i++) {
if (read) {
if (!DEBUG_IntVars[i].pval) {
if (!RegQueryValueEx(hkey, DEBUG_IntVars[i].name, 0,
&type, (LPSTR)&val, &count))
DEBUG_IntVars[i].val = val;
DEBUG_IntVars[i].pval = &DEBUG_IntVars[i].val;
} else {
*DEBUG_IntVars[i].pval = 0;
}
} else {
/* FIXME: type should be infered from basic type -if any- of intvar */
if (DEBUG_IntVars[i].pval == &DEBUG_IntVars[i].val)
RegSetValueEx(hkey, DEBUG_IntVars[i].name, 0,
type, (LPCVOID)DEBUG_IntVars[i].pval, count);
}
}
RegCloseKey(hkey);
}
return TRUE;
}
DBG_INTVAR* DEBUG_GetIntVar(const char* name)
{
int i;
for (i = 0; i < DBG_IV_LAST; i++) {
if (!strcmp(DEBUG_IntVars[i].name, name))
return &DEBUG_IntVars[i];
}
return NULL;
}
static WINE_EXCEPTION_FILTER(wine_dbg)
{
DEBUG_ExternalDebugger();
@ -119,18 +152,6 @@ static void DEBUG_DelProcess(DBG_PROCESS* p)
static void DEBUG_InitCurrProcess(void)
{
#ifdef DBG_need_heap
/*
* Initialize the debugger heap.
*/
dbg_heap = HeapCreate(HEAP_NO_SERIALIZE, 0x1000, 0x8000000); /* 128MB */
#endif
/*
* Initialize the type handling stuff.
*/
DEBUG_InitTypes();
DEBUG_InitCVDataTypes();
}
static BOOL DEBUG_ProcessGetString(char* buffer, int size, HANDLE hp, LPSTR addr)
@ -277,6 +298,8 @@ static BOOL DEBUG_HandleException( EXCEPTION_RECORD *rec, BOOL first_chance, BOO
case EXCEPTION_CRITICAL_SECTION_WAIT:
DEBUG_Printf( DBG_CHN_MESG, "critical section %08lx wait failed",
rec->ExceptionInformation[0] );
if (!DBG_IVAR(BreakOnCritSectTimeOut))
return DBG_CONTINUE;
break;
default:
DEBUG_Printf( DBG_CHN_MESG, "%08lx", rec->ExceptionCode );
@ -284,6 +307,8 @@ static BOOL DEBUG_HandleException( EXCEPTION_RECORD *rec, BOOL first_chance, BOO
}
}
DEBUG_Printf(DBG_CHN_MESG, "\n");
DEBUG_Printf(DBG_CHN_TRACE,
"Entering debugger PC=%lx EFL=%08lx mode=%d count=%d\n",
DEBUG_context.Eip, DEBUG_context.EFlags,
@ -503,7 +528,7 @@ static BOOL DEBUG_HandleDebugEvent(DEBUG_EVENT* de, LPDWORD cont)
return ret;
}
static DWORD CALLBACK DEBUG_MainLoop(DWORD pid)
static DWORD DEBUG_MainLoop(DWORD pid)
{
DEBUG_EVENT de;
DWORD cont;
@ -511,8 +536,6 @@ static DWORD CALLBACK DEBUG_MainLoop(DWORD pid)
DEBUG_Printf(DBG_CHN_MESG, " on pid %ld\n", pid);
DEBUG_Init();
while (ret && WaitForDebugEvent(&de, INFINITE)) {
ret = DEBUG_HandleDebugEvent(&de, &cont);
ContinueDebugEvent(de.dwProcessId, de.dwThreadId, cont);
@ -520,78 +543,78 @@ static DWORD CALLBACK DEBUG_MainLoop(DWORD pid)
DEBUG_Printf(DBG_CHN_MESG, "WineDbg terminated on pid %ld\n", pid);
ExitProcess(0);
return 0;
}
int PASCAL WinMain(HINSTANCE hInst, HINSTANCE prev, LPSTR _cmdline, int show)
int DEBUG_main(int argc, char** argv)
{
char* argv[5];
char* cmdline = strdup(_cmdline);
char* ptr = cmdline;
int instr = FALSE;
int argc = 0;
DWORD pid = 0, retv = 0;
int i;
while ((*ptr == ' ' || *ptr == '\t') && *ptr != 0) ptr++;
argv[argc++] = ptr;
for (; *ptr; ptr++) {
if ((*ptr == ' ' || *ptr == '\t') && !instr) {
*ptr++ = 0;
while (*ptr == ' ' || *ptr == '\t') ptr++;
if (*ptr) argv[argc++] = ptr;
if (argc >= sizeof(argv) / sizeof(argv[0])) return 0;
} else if (*ptr == '"') {
instr = !instr;
}
}
for (i = 0; i < argc; i++) fprintf(stderr, "argv[%d]=%s\n", i, argv[i]);
#ifdef DBG_need_heap
/* Initialize the debugger heap. */
dbg_heap = HeapCreate(HEAP_NO_SERIALIZE, 0x1000, 0x8000000); /* 128MB */
#endif
/* Initialize the type handling stuff. */
DEBUG_InitTypes();
DEBUG_InitCVDataTypes();
/* Initialize internal vars */
DEBUG_IntVarsRW(TRUE);
#if 0
/* would require to change .spec with a cuiexe type */
/* keep it as a guiexe for now, so that Wine won't touch the Unix stdin,
* stdout and stderr streams
*/
if (1 /*DBG_IVAR(UseXterm)*/) {
if (DBG_IVAR(UseXTerm)) {
COORD pos;
/* This is a hack: it forces creation of an xterm, not done by default */
pos.x = 0; pos.y = 1;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
#endif
DEBUG_Printf(DBG_CHN_MESG, "Starting WineDbg... ");
if (argc == 2) {
DWORD pid = atoi(argv[0]);
HANDLE hEvent = atoi(argv[1]);
if (pid != 0 && hEvent != 0) {
free(cmdline);
if (argc == 3) {
HANDLE hEvent;
if ((pid = atoi(argv[1])) != 0 && (hEvent = atoi(argv[2])) != 0) {
if (!DebugActiveProcess(pid)) {
DEBUG_Printf(DBG_CHN_ERR, "Can't attach process %ld: %ld\n",
pid, GetLastError());
return 0;
SetEvent(hEvent);
goto leave;
}
SetEvent(hEvent);
return DEBUG_MainLoop(pid);
} else {
pid = 0;
}
}
do {
if (pid == 0) {
PROCESS_INFORMATION info;
STARTUPINFOA startup;
free(cmdline);
memset(&startup, 0, sizeof(startup));
startup.cb = sizeof(startup);
startup.dwFlags = STARTF_USESHOWWINDOW;
startup.wShowWindow = SW_SHOWNORMAL;
if (CreateProcess(NULL, _cmdline, NULL, NULL,
if (!CreateProcess(NULL, argv[1], NULL, NULL,
FALSE, DEBUG_PROCESS, NULL, NULL, &startup, &info)) {
return DEBUG_MainLoop(info.dwProcessId);
DEBUG_Printf(DBG_CHN_MESG, "Couldn't start process '%s'\n", argv[1]);
goto leave;
}
DEBUG_Printf(DBG_CHN_MESG, "Couldn't start process '%s'\n", _cmdline);
} while (0);
return 0;
pid = info.dwProcessId;
}
if (pid) retv = DEBUG_MainLoop(pid);
leave:
/* saves modified variables */
DEBUG_IntVarsRW(FALSE);
return retv;
}

View File

@ -1,5 +1,5 @@
name winedbg
mode guiexe
mode cuiexe
type win32
init WinMain
init DEBUG_main