mirror of
https://github.com/reactos/wine.git
synced 2024-11-28 06:00:45 +00:00
- 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:
parent
8446ba04ab
commit
04c16b828e
@ -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 */
|
||||
|
||||
|
@ -62,7 +62,6 @@
|
||||
* Instruction disassembler.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "debugger.h"
|
||||
|
||||
#ifdef __i386__
|
||||
|
@ -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:
|
||||
@ -313,11 +308,10 @@ expr_addr:
|
||||
expr { $$ = DEBUG_EvalExpr($1); }
|
||||
|
||||
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; }
|
||||
expr { DBG_VALUE value = DEBUG_EvalExpr($1);
|
||||
/* expr_value is typed as an integer */
|
||||
$$ = 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); }
|
||||
|
@ -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; }
|
||||
@ -155,7 +124,7 @@ $gs { yylval.reg = REG_GS; return tREG; }
|
||||
|
||||
<INFO_CMD>share|shar|sha { return tSHARE; }
|
||||
<INFO_CMD>locals|local|loca|loc { return tLOCAL; }
|
||||
<INFO_CMD,WALK_CMD>class|clas|cla { return tCLASS; }
|
||||
<INFO_CMD,WALK_CMD>class|clas|cla { return tCLASS; }
|
||||
<INFO_CMD,WALK_CMD>module|modul|modu|mod { return tMODULE; }
|
||||
<INFO_CMD,WALK_CMD>queue|queu|que { return tQUEUE; }
|
||||
<INFO_CMD,WALK_CMD>process|proces|proce|proc { return tPROCESS; }
|
||||
@ -163,7 +132,7 @@ $gs { yylval.reg = REG_GS; return tREG; }
|
||||
<INFO_CMD,WALK_CMD>modref|modre|modr { return tMODREF; }
|
||||
<INFO_CMD>registers|regs|reg|re { return tREGS; }
|
||||
<INFO_CMD>segments|segment|segm|seg|se { return tSEGMENTS; }
|
||||
<INFO_CMD>stack|stac|sta|st { return tSTACK; }
|
||||
<INFO_CMD>stack|stac|sta|st { return tSTACK; }
|
||||
<INFO_CMD>maps|map { return tMAPS; }
|
||||
<INFO_CMD,WALK_CMD>window|windo|wind|win|wnd { return tWND; }
|
||||
<HELP_CMD>info|inf|in { return tINFO; }
|
||||
@ -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;
|
||||
|
@ -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 int DEBUG_Printf(int chn, const char* format, ...);
|
||||
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 */
|
||||
|
@ -6,7 +6,6 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -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);
|
||||
if (Reset == 0) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
||||
|
||||
#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" );
|
||||
return EOF;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
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 );
|
||||
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;
|
||||
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;
|
||||
|
@ -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;
|
||||
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
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;
|
||||
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;
|
||||
|
||||
DEBUG_FixAddress( &addr, DEBUG_context.SegDs );
|
||||
lin = (void*)DEBUG_ToLinear( &addr );
|
||||
|
||||
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;
|
||||
void* lin;
|
||||
int os = DEBUG_GetObjectSize(val->type);
|
||||
|
||||
DEBUG_FixAddress( &addr, DEBUG_context.SegDs );
|
||||
lin = (void*)DEBUG_ToLinear( &addr );
|
||||
DEBUG_WRITE_MEM_VERBOSE(lin, &value, sizeof(value));
|
||||
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, 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;
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
@ -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' )
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -8,7 +8,6 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "debugger.h"
|
||||
|
@ -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 )
|
||||
{
|
||||
|
@ -26,47 +26,80 @@ 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)
|
||||
{
|
||||
@ -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,87 +536,85 @@ 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);
|
||||
}
|
||||
|
||||
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,
|
||||
FALSE, DEBUG_PROCESS, NULL, NULL, &startup, &info)) {
|
||||
return DEBUG_MainLoop(info.dwProcessId);
|
||||
if (!CreateProcess(NULL, argv[1], NULL, NULL,
|
||||
FALSE, DEBUG_PROCESS, NULL, NULL, &startup, &info)) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
name winedbg
|
||||
mode guiexe
|
||||
mode cuiexe
|
||||
type win32
|
||||
init WinMain
|
||||
init DEBUG_main
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user