Added ability to execute commands from a file passed on command line

(through --file option).
Use that feature to get rid of arg_command hack (--command option now
creates a temporary file).
This commit is contained in:
Eric Pouech 2005-11-16 11:23:07 +00:00 committed by Alexandre Julliard
parent 2ca23be50f
commit 1c5d35fd92
4 changed files with 83 additions and 36 deletions

View file

@ -452,24 +452,12 @@ static void stripwhite(char *string)
static HANDLE dbg_parser_input;
static HANDLE dbg_parser_output;
/* command passed in the command line arguments */
char *arg_command = NULL;
int input_fetch_entire_line(const char* pfx, char** line, size_t* alloc, BOOL check_nl)
{
char buf_line[256];
DWORD nread, nwritten;
size_t len;
if (arg_command) {
/* we only run one command before exiting */
const char q[] = "quit\n";
*line = arg_command;
arg_command = HeapAlloc(GetProcessHeap(), 0, sizeof q);
lstrcpyA(arg_command, q);
return 1;
}
/* as of today, console handles can be file handles... so better use file APIs rather than
* console's
*/
@ -529,11 +517,11 @@ int input_read_line(const char* pfx, char* buf, int size)
}
/***********************************************************************
* parser
* parser_handle
*
* Debugger command line parser
*/
void parser(const char* filename)
void parser_handle(HANDLE input)
{
BOOL ret_ok;
HANDLE in_copy = dbg_parser_input;
@ -545,12 +533,10 @@ void parser(const char* filename)
ret_ok = FALSE;
if (filename)
if (input != INVALID_HANDLE_VALUE)
{
HANDLE h = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0L, 0);
if (h == INVALID_HANDLE_VALUE) return;
dbg_parser_output = 0;
dbg_parser_input = h;
dbg_parser_output = INVALID_HANDLE_VALUE;
dbg_parser_input = input;
}
else
{
@ -573,11 +559,20 @@ void parser(const char* filename)
lexeme_flush();
} while (!ret_ok);
if (filename) CloseHandle(dbg_parser_input);
dbg_parser_input = in_copy;
dbg_parser_output = out_copy;
}
void parser(const char* filename)
{
HANDLE h = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0L, 0);
if (h != INVALID_HANDLE_VALUE)
{
parser_handle(h);
CloseHandle(h);
}
}
int yyerror(const char* s)
{
dbg_printf("%s\n", s);

View file

@ -122,8 +122,6 @@ enum dbg_exec_mode
#endif
};
extern char *arg_command;
struct dbg_breakpoint
{
ADDRESS addr;
@ -268,6 +266,7 @@ extern int break_add_condition(int bpnum, struct expr* exp);
/* dbg.y */
extern void parser(const char*);
extern void parser_handle(HANDLE);
extern int input_read_line(const char* pfx, char* buffer, int size);
extern int input_fetch_entire_line(const char* pfx, char** line, size_t* alloc, BOOL check_nl);

View file

@ -69,6 +69,18 @@
* we have a multi-thread debuggee). complete fix must include storing all
* thread's step-over bp in process-wide bp array, and not to handle bp
* when we have the wrong thread running into that bp
* + code in CREATE_PROCESS debug event doesn't work on Windows, as we cannot
* get the name of the main module this way. We should rewrite all this code
* and store in struct dbg_process as early as possible (before process
* creation or attachment), the name of the main module
* - global:
* + define a better way to enable the wine extensions (either DBG SDK function
* in dbghelp, or TLS variable, or environment variable or ...)
* + audit all files to ensure that we check all potential return values from
* every function call to catch the errors
* + BTW check also whether the exception mechanism is the best way to return
* errors (or find a proper fix for MinGW port)
* + use Wine standard list mechanism for all list handling
*/
WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
@ -1038,7 +1050,7 @@ void dbg_wait_next_exception(DWORD cont, int count, int mode)
dbg_curr_thread->exec_count);
}
static unsigned dbg_main_loop(void)
static unsigned dbg_main_loop(HANDLE hFile)
{
DEBUG_EVENT de;
@ -1061,7 +1073,7 @@ static unsigned dbg_main_loop(void)
break;
default:
dbg_interactiveP = TRUE;
parser(NULL);
parser_handle(hFile);
}
dbg_printf("WineDbg terminated on pid 0x%lx\n", dbg_curr_pid);
@ -1170,7 +1182,7 @@ static void dbg_init_console(void)
static int dbg_winedbg_usage(void)
{
dbg_printf("Usage: winedbg [--command cmd|--auto] [--gdb [--no-start] [--with-xterm]] cmdline\n");
dbg_printf("Usage: winedbg [--command cmd|--file file|--auto] [--gdb [--no-start] [--with-xterm]] cmdline\n");
return 1;
}
@ -1189,6 +1201,7 @@ int main(int argc, char** argv)
{
DWORD retv = 0;
unsigned gdb_flags = 0;
HANDLE hFile = INVALID_HANDLE_VALUE;
#ifdef __i386__
be_cpu = &be_i386;
@ -1210,10 +1223,36 @@ int main(int argc, char** argv)
{
if (!strcmp(argv[1], "--command"))
{
char path[MAX_PATH], file[MAX_PATH];
DWORD w;
GetTempPath(sizeof(path), path);
GetTempFileName(path, "WD", 0, file);
argc--; argv++;
arg_command = HeapAlloc(GetProcessHeap(), 0, strlen(argv[1])+2);
strcpy(arg_command, argv[1]);
strcat(arg_command, "\n");
hFile = CreateFileA(file, GENERIC_READ|GENERIC_WRITE|DELETE, FILE_SHARE_DELETE,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0);
if (hFile == INVALID_HANDLE_VALUE)
{
dbg_printf("Couldn't open temp file %s (%lu)\n", file, GetLastError());
return 1;
}
WriteFile(hFile, argv[1], strlen(argv[1]), &w, 0);
WriteFile(hFile, "\nquit\n", 6, &w, 0);
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
argc--; argv++;
continue;
}
if (!strcmp(argv[1], "--file"))
{
argc--; argv++;
hFile = CreateFileA(argv[1], GENERIC_READ|DELETE, 0,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile == INVALID_HANDLE_VALUE)
{
dbg_printf("Couldn't open file %s (%lu)\n", argv[1], GetLastError());
return 1;
}
argc--; argv++;
continue;
}
@ -1258,7 +1297,7 @@ int main(int argc, char** argv)
dbg_curr_pid = strtol(argv[1], &ptr, 10);
if (dbg_curr_pid == 0 || ptr != argv[1] + strlen(argv[1]) ||
!dbg_attach_debuggee(dbg_curr_pid, dbg_action_mode != gdb_mode, FALSE))
!dbg_attach_debuggee(dbg_curr_pid, FALSE, FALSE))
dbg_curr_pid = 0;
}
@ -1322,7 +1361,7 @@ int main(int argc, char** argv)
SymSetOptions((SymGetOptions() & ~(SYMOPT_UNDNAME)) |
SYMOPT_LOAD_LINES | SYMOPT_DEFERRED_LOADS | SYMOPT_AUTO_PUBLICS);
retv = dbg_main_loop();
retv = dbg_main_loop(hFile);
/* don't save modified variables in auto mode */
if (dbg_action_mode != automatic_mode) dbg_save_internal_vars();

View file

@ -3,7 +3,9 @@
.SH NAME
winedbg \- Wine's debugger
.SH SYNOPSIS
.BR "winedbg " [ " --auto" " |"
.BR "winedbg ["
.RI "[ " " options " "]"
.BR "| --auto |"
.BI "--gdb"
.RI "[" " options " "] ] ["
.BI "program name"
@ -42,7 +44,19 @@ the front end for command handling, and \fBwinedbg\fR will proxy all
debugging requests from \fBgdb\fR to the Win32 APIs.
.SH OPTIONS
Only the \fBgdb\fR proxy mode allows some options:
When in \fBdefault\fR mode, the following options are available:
.PP
.IP \fI--command\ <string>\fR
\fBwinedbg\fR will execute the command <string> as if it was keyed on
winedbg's command line, and then will exit. This can be handy for
getting the pid of running processes (winedbg --command "info proc").
.IP \fI--file\ <filename>\fR
\fBwinedbg\fR will execute the list of commands contained in file
<filename> as if they were keyed on winedbg's command line, and then
will exit.
.PP
When in \fBgdb\fR proxy mode, the following options are available:
.PP
.IP \fI--no-start\fR \fBgdb\fR will not be automatically
started. Relevant information for starting \fBgdb\fR are printed on
@ -52,18 +66,18 @@ some graphical front-ends, like \fBddd\fR or \fBkgbd\fR.
This will run \fBgdb\fR in its own xterm instead of using the current
Unix console for textual display.
.PP
The rest of the command line, when passed, is used to identify which
programs, if any, has to debugged:
In all modes, the rest of the command line, when passed, is used to
identify which programs, if any, has to debugged:
.IP \fBprogram\ name\fR
This is the name of an executable to start for a debugging
session. \fBwinedbg\fR will actually create a process with this
executable. If \fBprograms arguments\fR are also given, they will be
used as arguments for creating the process to be debugged.
.IP \fBpid\fR
\fBgdb\fR will attach to the process which pid is \fBpid\fR (pids
\fBwinedbg\fR will attach to the process which pid is \fBpid\fR (pids
refer to Win32 pids, not Unix pids). Use the \fIinfo proc\fR
\fBwinedbg\fR command to list running processes and their Win32 pids.
.IP \fBdefaut\fR
.IP \fBdefault\fR
If nothing is specified, you will enter the debugger without any run
nor attached process. You'll have to do the job yourself.