[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