[PATCH] [WineDbg test harness]: various updates
Eric Pouech
eric.pouech at wanadoo.fr
Sun Mar 5 14:48:44 CST 2006
- now supports all tests with or without 'in <modname>' information
- extended startup tests
A+
---
programs/winedbg/tests/start.c | 77 +++++++++++++++++++++++++++++-----
programs/winedbg/tests/test_cl.h | 28 +++++++-----
programs/winedbg/tests/wdbgtest.h | 83 +++++++++++++++++++++++++++++++------
3 files changed, 151 insertions(+), 37 deletions(-)
diff --git a/programs/winedbg/tests/start.c b/programs/winedbg/tests/start.c
index 1e97038..5f0dfdb 100644
--- a/programs/winedbg/tests/start.c
+++ b/programs/winedbg/tests/start.c
@@ -25,6 +25,7 @@
* - should also test that winedbg starts upon exception
* - first chance & second chance exceptions should be tested
* - winedbg invocation with a set of commands passed on the command line
+ * (done but rather ugly)
* - winedbg invocation with a file as commands
* - winedbg invocation in automatic mode
*/
@@ -46,7 +47,16 @@ static void simple(struct debuggee* dbg)
ok(ret != -1, "%s\n", dbg->err_msg);
}
-static void test_cmdline(void)
+static void test_cl_no_arg(void)
+{
+ struct debuggee dbg;
+ int ret;
+
+ ret = wdt_start(&dbg, "../winedbg.exe.so");
+ ok(ret != -1, "%s\n", dbg.err_msg);
+}
+
+static void test_cl_cmdline(void)
{
struct debuggee dbg;
int ret;
@@ -56,7 +66,7 @@ static void test_cmdline(void)
simple(&dbg);
}
-static void test_attach(void)
+static void test_cl_pid(void)
{
struct debuggee dbg;
HANDLE hEvent;
@@ -91,24 +101,67 @@ static void test_attach(void)
}
#if 0
-static void test_cl_file(void)
+static void test_crash(void)
{
struct debuggee dbg;
int ret;
- ret = wdt_start(&dbg, "../winedbg.exe.so --command \\\\\"break start_real\\\\\" wdtp.exe.so start");
+ ret = wdt_start(&dbg, "wdtp.exe.so start --crash");
ok(ret != -1, "%s\n", dbg.err_msg);
- CloseHandle(dbg.cl.hOutput);
- dbg.cl.hOutput = CreateFileA("NUL", GENERIC_READ|GENERIC_WRITE,
- FILE_SHARE_DELETE, NULL, CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL, 0);
- ok(dbg.cl.hOutput != INVALID_HANDLE_VALUE, "cannot open NUL\n");
- simple(&dbg);
+ printf("--> %s\n", dbg.cl.buffer);
}
#endif
+static void test_cl_cmd(void)
+{
+ struct debuggee dbg;
+ int ret;
+ BOOL eof;
+ char tmp[1024], *end;
+ struct location loc;
+
+ /* FIXME: this whole test is ugly as hell... */
+ memset(&dbg, 0, sizeof(dbg));
+ /* cannot use wtcl_start because we won't get the prompt for synchro */
+ ret = wtcl_start(&dbg.cl, "../winedbg.exe.so --command \"break start_real\" wdtp.exe.so start");
+ ok(ret != -1, "%s\n", dbg.err_msg);
+
+ /* fetch whole buffer (FIXME overflow) */
+ ret = _wtcl_recv_raw_b(&dbg.cl, tmp, sizeof(tmp), 10, &eof);
+
+ /* some black magic incantation to get the string we're looking for */
+ tmp[ret] = '\0';
+ dbg.cl.buffer = tmp;
+ dbg.cl.buf_ptr = strstr(tmp, "Breakp");
+ ok(dbg.cl.buf_ptr != NULL, "Couldn't find Breakp [[[\n%s\n]]]\n", tmp);
+ end = strchr(dbg.cl.buf_ptr, '\n');
+ ok(end != NULL, "Couldn't find '\\n' [[[\n%s\n]]]\n", tmp);
+ *end = '\0';
+
+ /* and doing the check by hand */
+ if (_compare(re_set_break_m, dbg.cl.buf_ptr))
+ {
+ ok(_to_num(&dbg, 1) == 1, "wrong bp number");
+ _grab_location(&dbg, &loc, 2, 3, 4, 5, 6);
+ }
+ else if (_compare(re_set_break_b, dbg.cl.buf_ptr))
+ {
+ ok(_to_num(&dbg, 1) == 1, "wrong bp number");
+ _grab_location(&dbg, &loc, 2, 3, 4, 5, -1);
+ }
+ else ok(0, "no RE found\n");
+ ok(!strcmp("start_real", loc.name), "wrong bp name '%s'\n", loc.name);
+ ok(wdt_ends_with(loc.srcfile, "wdtp_start.c"), "wrong src file %s\n", loc.srcfile);
+ ok(loc.lineno == 11, "wrong lineno %d\n", loc.lineno);
+ wdt_free_location(&loc);
+
+ wtcl_stop(&dbg.cl);
+}
+
START_TEST(start)
{
- test_cmdline();
- test_attach();
+ test_cl_no_arg();
+ test_cl_cmdline();
+ test_cl_pid();
+ test_cl_cmd();
}
diff --git a/programs/winedbg/tests/test_cl.h b/programs/winedbg/tests/test_cl.h
index 97a5daf..bd5dcbb 100644
--- a/programs/winedbg/tests/test_cl.h
+++ b/programs/winedbg/tests/test_cl.h
@@ -71,6 +71,17 @@ static inline void wtcl_set_timeout(stru
cci->timeout = to;
}
+static inline void wtcl_stop(struct cl_child_info* cci)
+{
+ TerminateProcess(cci->info.hProcess, 0);
+ CloseHandle(cci->hInput);
+ CloseHandle(cci->hOutput);
+ CloseHandle(cci->info.hThread);
+ CloseHandle(cci->info.hProcess);
+ wtcl_set_prompt(cci, NULL);
+ memset(cci, 0xA5, sizeof(*cci));
+}
+
static inline int wtcl_start(struct cl_child_info* cci, char* cmdline)
{
HANDLE hChildOut, hChildOutInh;
@@ -95,7 +106,11 @@ static inline int wtcl_start(struct cl_c
startup.hStdOutput = hChildOutInh;
startup.hStdError = hChildOutInh;
- CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &startup, &cci->info);
+ if (!CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &startup, &cci->info))
+ {
+ wtcl_stop(cci);
+ return -1;
+ }
CloseHandle(hChildInInh);
CloseHandle(hChildOutInh);
@@ -103,17 +118,6 @@ static inline int wtcl_start(struct cl_c
return 0;
}
-static inline void wtcl_stop(struct cl_child_info* cci)
-{
- TerminateProcess(cci->info.hProcess, 0);
- CloseHandle(cci->hInput);
- CloseHandle(cci->hOutput);
- CloseHandle(cci->info.hThread);
- CloseHandle(cci->info.hProcess);
- wtcl_set_prompt(cci, NULL);
- memset(cci, 0xA5, sizeof(*cci));
-}
-
static inline int wtcl_send_vcmd(struct cl_child_info* cci, const char* msg, va_list valist)
{
char buffer[1024];
diff --git a/programs/winedbg/tests/wdbgtest.h b/programs/winedbg/tests/wdbgtest.h
index 967b0df..475bfb0 100644
--- a/programs/winedbg/tests/wdbgtest.h
+++ b/programs/winedbg/tests/wdbgtest.h
@@ -1,6 +1,6 @@
/* WineDbg test
* Helper routines for testing WineDbg
- * Copyright 2005 Eric Pouech
+ * Copyright 2005-2006 Eric Pouech
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -115,8 +115,10 @@ re[] =
{
/* RE for execution ---------- */
/* re_started */ {"^WineDbg starting on pid (0x[0-9a-fA-F]+)$", 1},
- /* re_stopped_bp */ {"^Stopped on breakpoint ([0-9]+) at (0x[0-9a-fA-F]+) ([^ ]+) \\[(.*):([0-9]+)\\] in ([^\n]*)", 6},
- /* re_stopped_wp */ {"^Stopped on watchpoint ([0-9]+) at (0x[0-9a-fA-F]+) ([^ ]+) \\[(.*):([0-9]+)\\] in ([^\n]*) values: old=[0-9]+ new=[0-9]+", 6},
+ /* re_stopped_bp_m */ {"^Stopped on breakpoint ([0-9]+) at (0x[0-9a-fA-F]+) ([^ ]+) \\[(.*):([0-9]+)\\] in ([^\n]*)", 6},
+ /* re_stopped_bp_b */ {"^Stopped on breakpoint ([0-9]+) at (0x[0-9a-fA-F]+) ([^ ]+) \\[(.*):([0-9]+)\\]", 5},
+ /* re_stopped_wp_m */ {"^Stopped on watchpoint ([0-9]+) at (0x[0-9a-fA-F]+) ([^ ]+) \\[(.*):([0-9]+)\\] in ([^\n]*) values: old=[0-9]+ new=[0-9]+", 6},
+ /* re_stopped_wp_b */ {"^Stopped on watchpoint ([0-9]+) at (0x[0-9a-fA-F]+) ([^ ]+) \\[(.*):([0-9]+)\\] values: old=[0-9]+ new=[0-9]+", 5},
/* re_terminated */ {"^WineDbg terminated on pid (0x[0-9a-fA-F]+)$", 1},
/* re_srcline */ {"^([0-9]+)", 1},
/* re_asmline */ {"^(0x[0-9a-fA-F]+) ([^ ]*) in ([^:]*):", 3},
@@ -130,15 +132,18 @@ re[] =
/* re_struct */ {"^\\{(.*)\\}$", 1},
/* re_func */ {"^Function (0x[0-9a-fA-F]+): (.*)$", 2},
/* RE for commands ----------- */
- /* re_set_break */ {"^Breakpoint ([0-9]+) at (0x[0-9a-fA-F]+) ([^ ]+) \\[(.*):([0-9]+)\\] in ([^\n]*)$", 6},
- /* re_set_watch1 */ {"^Watchpoint ([0-9]+) at (0x[0-9a-fA-F]+) ([^ ]+) in ([^\n]*)$", 4},
- /* re_set_watch2 */ {"^Watchpoint ([0-9]+) at (0x[0-9a-fA-F]+)$", 2},
- /* re_backtrace */ {"^[= ][> ]([0-9]+) (0x[0-9a-fA-F]+) ([^\\(]*)\\(([^\\)]*)\\) \\[([^\n]*):([0-9]+)\\] in ([^ ]*) \\((0x[0-9a-fA-F]+)\\)\n", 8},
+ /* re_set_break_m */ {"^Breakpoint ([0-9]+) at (0x[0-9a-fA-F]+) ([^ ]+) \\[(.*):([0-9]+)\\] in ([^\n]*)$", 6},
+ /* re_set_break_b */ {"^Breakpoint ([0-9]+) at (0x[0-9a-fA-F]+) ([^ ]+) \\[(.*):([0-9]+)\\]$", 5},
+ /* re_set_watch1_m */ {"^Watchpoint ([0-9]+) at (0x[0-9a-fA-F]+) ([^ ]+) in ([^\n]*)$", 4},
+ /* re_set_watch1_b */ {"^Watchpoint ([0-9]+) at (0x[0-9a-fA-F]+) ([^ ]+)$", 3},
+ /* re_set_watch2 */ {"^Watchpoint ([0-9]+) at (0x[0-9a-fA-F]+)$", 2},
+ /* re_backtrace_m */ {"^[= ][> ]([0-9]+) (0x[0-9a-fA-F]+) ([^\\(]*)\\(([^\\)]*)\\) \\[([^\n]*):([0-9]+)\\] in ([^ ]*) \\((0x[0-9a-fA-F]+)\\)\n", 8},
+ /* re_backtrace_b */ {"^[= ][> ]([0-9]+) (0x[0-9a-fA-F]+) ([^\\(]*)\\(([^\\)]*)\\) \\[([^\n]*):([0-9]+)\\] \\((0x[0-9a-fA-F]+)\\)\n", 7},
};
/* Each entry in this enum matches a RE in previous array. Be sure to keep them in sync */
-enum re_val {re_started, re_stopped_bp, re_stopped_wp, re_terminated, re_srcline, re_asmline, re_funcchange, re_display,
+enum re_val {re_started, re_stopped_bp_m, re_stopped_bp_b, re_stopped_wp_m, re_stopped_wp_b, re_terminated, re_srcline, re_asmline, re_funcchange, re_display,
re_integer, re_hexa, re_string, re_char, re_struct, re_func,
- re_set_break, re_set_watch1, re_set_watch2, re_backtrace,
+ re_set_break_m, re_set_break_b, re_set_watch1_m, re_set_watch1_b, re_set_watch2, re_backtrace_m, re_backtrace_b,
re_last};
static regmatch_t rm[9];
@@ -437,7 +442,7 @@ static inline int wdt_execute(struct deb
/* different possible outputs:
* Breakpoint (bpnum) at 0x(addr) (name) [(srcfile):(lineno)] in (module) (refcount=2)
*/
- if (_compare(re_stopped_bp, dbg->cl.buf_ptr) || _compare(re_stopped_wp, dbg->cl.buf_ptr))
+ if (_compare(re_stopped_bp_m, dbg->cl.buf_ptr) || _compare(re_stopped_wp_m, dbg->cl.buf_ptr))
{
trace("Stopped at xp='%.*s' addr='%.*s' name='%.*s' src='%.*s'/line=%.*s module='%.*s'\n",
(int)(rm[1].rm_eo - rm[1].rm_so), &dbg->cl.buf_ptr[rm[1].rm_so],
@@ -451,6 +456,19 @@ static inline int wdt_execute(struct deb
wdt_free_location(&dbg->loc);
_grab_location(dbg, &dbg->loc, 2, 3, 4, 5, 6);
}
+ else if (_compare(re_stopped_bp_b, dbg->cl.buf_ptr) || _compare(re_stopped_wp_b, dbg->cl.buf_ptr))
+ {
+ trace("Stopped at xp='%.*s' addr='%.*s' name='%.*s' src='%.*s'/line=%.*s\n",
+ (int)(rm[1].rm_eo - rm[1].rm_so), &dbg->cl.buf_ptr[rm[1].rm_so],
+ (int)(rm[2].rm_eo - rm[2].rm_so), &dbg->cl.buf_ptr[rm[2].rm_so],
+ (int)(rm[3].rm_eo - rm[3].rm_so), &dbg->cl.buf_ptr[rm[3].rm_so],
+ (int)(rm[4].rm_eo - rm[4].rm_so), &dbg->cl.buf_ptr[rm[4].rm_so],
+ (int)(rm[5].rm_eo - rm[5].rm_so), &dbg->cl.buf_ptr[rm[5].rm_so]);
+ dbg->status = ss_xpoint;
+ dbg->info = _to_num(dbg, 1);
+ wdt_free_location(&dbg->loc);
+ _grab_location(dbg, &dbg->loc, 2, 3, 4, 5, -1);
+ }
else if (_compare(re_funcchange, dbg->cl.buf_ptr))
{
trace("Entering function %.*s src='%.*s'/line=%.*s\n",
@@ -502,7 +520,7 @@ static inline int wdt_set_xpoint(struct
trace("Got for cmd='%s': '%s'\n", cmd, dbg->cl.buf_ptr);
/* Breakpoint 1 at 0x???????? main [srcfile:lineno] in module */
- if (_compare(re_set_break, dbg->cl.buf_ptr))
+ if (_compare(re_set_break_m, dbg->cl.buf_ptr))
{
trace("Found bp='%.*s' addr='%.*s' name='%.*s' src='%.*s'/lineno='%.*s' module='%.*s'\n",
(int)(rm[1].rm_eo - rm[1].rm_so), &dbg->cl.buf_ptr[rm[1].rm_so],
@@ -517,7 +535,21 @@ static inline int wdt_set_xpoint(struct
_grab_location(dbg, loc, 2, 3, 4, 5, 6);
}
}
- else if (_compare(re_set_watch1, dbg->cl.buf_ptr))
+ else if (_compare(re_set_break_b, dbg->cl.buf_ptr))
+ {
+ trace("Found bp='%.*s' addr='%.*s' name='%.*s' src='%.*s'/lineno='%.*s'\n",
+ (int)(rm[1].rm_eo - rm[1].rm_so), &dbg->cl.buf_ptr[rm[1].rm_so],
+ (int)(rm[2].rm_eo - rm[2].rm_so), &dbg->cl.buf_ptr[rm[2].rm_so],
+ (int)(rm[3].rm_eo - rm[3].rm_so), &dbg->cl.buf_ptr[rm[3].rm_so],
+ (int)(rm[4].rm_eo - rm[4].rm_so), &dbg->cl.buf_ptr[rm[4].rm_so],
+ (int)(rm[5].rm_eo - rm[5].rm_so), &dbg->cl.buf_ptr[rm[5].rm_so]);
+ if (xp_num) *xp_num = _to_num(dbg, 1);
+ if (loc)
+ {
+ _grab_location(dbg, loc, 2, 3, 4, 5, -1);
+ }
+ }
+ else if (_compare(re_set_watch1_m, dbg->cl.buf_ptr))
{
trace("Found wp='%.*s' addr='%.*s' name='%.*s' module='%.*s'\n",
(int)(rm[1].rm_eo - rm[1].rm_so), &dbg->cl.buf_ptr[rm[1].rm_so],
@@ -527,6 +559,15 @@ static inline int wdt_set_xpoint(struct
if (xp_num) *xp_num = _to_num(dbg, 1);
if (loc) _grab_location(dbg, loc, 2, 3, -1, -1, 4);
}
+ else if (_compare(re_set_watch1_b, dbg->cl.buf_ptr))
+ {
+ trace("Found wp='%.*s' addr='%.*s' name='%.*s'\n",
+ (int)(rm[1].rm_eo - rm[1].rm_so), &dbg->cl.buf_ptr[rm[1].rm_so],
+ (int)(rm[2].rm_eo - rm[2].rm_so), &dbg->cl.buf_ptr[rm[2].rm_so],
+ (int)(rm[3].rm_eo - rm[3].rm_so), &dbg->cl.buf_ptr[rm[3].rm_so]);
+ if (xp_num) *xp_num = _to_num(dbg, 1);
+ if (loc) _grab_location(dbg, loc, 2, 3, -1, -1, -1);
+ }
else if (_compare(re_set_watch2, dbg->cl.buf_ptr))
{
trace("Found wp='%.*s' addr='%.*s'\n",
@@ -549,7 +590,7 @@ static inline int wdt_backtrace_next(str
if (loc) memset(loc, 0, sizeof(*loc));
- if (_compare(re_backtrace, dbg->cl.buf_ptr))
+ if (_compare(re_backtrace_m, dbg->cl.buf_ptr))
{
/* FIXME:
* ebp -> _to_num(dbg, 8);
@@ -565,6 +606,22 @@ static inline int wdt_backtrace_next(str
if (args) *args = _to_string(dbg, 4);
dbg->cl.buf_ptr += (int)(rm[0].rm_eo - rm[0].rm_so);
}
+ else if (_compare(re_backtrace_b, dbg->cl.buf_ptr))
+ {
+ /* FIXME:
+ * ebp -> _to_num(dbg, 7);
+ */
+ trace("Found frame='%.*s' addr='%.*s' name='%.*s' srcfile='%.*s' args='%.*s'\n",
+ (int)(rm[1].rm_eo - rm[1].rm_so), &dbg->cl.buf_ptr[rm[1].rm_so],
+ (int)(rm[2].rm_eo - rm[2].rm_so), &dbg->cl.buf_ptr[rm[2].rm_so],
+ (int)(rm[3].rm_eo - rm[3].rm_so), &dbg->cl.buf_ptr[rm[3].rm_so],
+ (int)(rm[5].rm_eo - rm[5].rm_so), &dbg->cl.buf_ptr[rm[5].rm_so],
+ (int)(rm[4].rm_eo - rm[4].rm_so), &dbg->cl.buf_ptr[rm[4].rm_so]);
+ if (frame) *frame = _to_num(dbg, 1);
+ if (loc) _grab_location(dbg, loc, 2, 3, 5, 6, -1);
+ if (args) *args = _to_string(dbg, 4);
+ dbg->cl.buf_ptr += (int)(rm[0].rm_eo - rm[0].rm_so);
+ }
else
{
printf("No RE-backtrace for %s\n", dbg->cl.buf_ptr);
More information about the wine-patches
mailing list