From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4266 invoked by alias); 1 Jul 2009 19:31:41 -0000 Received: (qmail 4254 invoked by uid 22791); 1 Jul 2009 19:31:39 -0000 X-SWARE-Spam-Status: No, hits=-2.4 required=5.0 tests=AWL,BAYES_00,J_CHICKENPOX_14,J_CHICKENPOX_55,RCVD_IN_DNSWL_LOW,SPF_PASS X-Spam-Check-By: sourceware.org Received: from hel.is.scarlet.be (HELO hel.is.scarlet.be) (193.74.71.26) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 01 Jul 2009 19:31:32 +0000 Received: from [172.17.1.10] (ip-81-11-242-24.dsl.scarlet.be [81.11.242.24]) by hel.is.scarlet.be (8.14.2/8.14.2) with ESMTP id n61JVG49014437; Wed, 1 Jul 2009 21:31:16 +0200 Subject: Re: Patch : gdbserver get_image_name on CE From: Danny Backx Reply-To: danny.backx@scarlet.be To: Pedro Alves Cc: gdb-patches@sourceware.org In-Reply-To: <200906302258.00604.pedro@codesourcery.com> References: <1244903385.20290.9.camel@pavilion> <1245577804.15871.48.camel@pavilion> <1246396039.15871.152.camel@pavilion> <200906302258.00604.pedro@codesourcery.com> Content-Type: multipart/mixed; boundary="=-96TrWzxvAd7UO8yc9YqA" Date: Wed, 01 Jul 2009 19:31:00 -0000 Message-Id: <1246476684.15871.273.camel@pavilion> Mime-Version: 1.0 X-DCC-scarlet.be-Metrics: hel 20001; Body=3 Fuz1=3 Fuz2=3 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2009-07/txt/msg00041.txt.bz2 --=-96TrWzxvAd7UO8yc9YqA Content-Type: text/plain Content-Transfer-Encoding: 7bit Content-length: 626 On Tue, 2009-06-30 at 22:58 +0100, Pedro Alves wrote: > On Tuesday 30 June 2009 22:07:19, Danny Backx wrote: > > > > > Is the rest of my patch acceptable or are there things I need to > > > address ? > > > > > Did you get to confirm what really that ERROR_PIPE_NOT_CONNECTED > is about? > > http://sourceware.org/ml/gdb-patches/2009-06/msg00373.html > > Could you post an updated, cleaned up patch, without any extra > unnecessary bits removed, along with change log entry, using > 'cvs diff -up'? Attached. Comments, as always, welcome. Danny -- Danny Backx ; danny.backx - at - scarlet.be ; http://danny.backx.info --=-96TrWzxvAd7UO8yc9YqA Content-Disposition: attachment; filename="1" Content-Type: text/plain; name="1"; charset="UTF-8" Content-Transfer-Encoding: 7bit Content-length: 5476 2009-07-01 Danny Backx * win32-i386-low.c (i386_get_thread_context): Avoid failure by calling GetThreadContext with flags that don't work on every processor. Fall back to querying less registers if that happens. * win32-i386-low.c (the_low_target, i386_wince_breakpoint) : Implement breakpoints. * win32-low.c (get_image_name): Don't rely on return value of ReadProcessMemory. Comment where some of the code still relies on sizeof(WCHAR) == 2. * win32-low.c (get_child_debug_event): Detect and work around a known case where CreateProcess reports success but the inferior dies immediately. Index: win32-i386-low.c =================================================================== RCS file: /cvs/src/src/gdb/gdbserver/win32-i386-low.c,v retrieving revision 1.14 diff -u -u -p -r1.14 win32-i386-low.c --- win32-i386-low.c 3 Jan 2009 05:57:57 -0000 1.14 +++ win32-i386-low.c 1 Jul 2009 19:28:15 -0000 @@ -39,16 +39,36 @@ i386_initial_stuff (void) debug_registers_used = 0; } +/* + * According to Mike Stall's .net debugging blog + * (http://blogs.msdn.com/jmstall/archive/2005/01/18/355697.aspx) + * the CONTEXT_EXTENDED_REGISTERS flag must be omitted if hardware doesn't + * support it. So I guess the only reasonable thing to do is just try. + */ static void i386_get_thread_context (win32_thread_info *th, DEBUG_EVENT* current_event) { - th->context.ContextFlags = \ - CONTEXT_FULL | \ - CONTEXT_FLOATING_POINT | \ - CONTEXT_EXTENDED_REGISTERS | \ + /* try all flags */ + th->context.ContextFlags = + CONTEXT_FULL | + CONTEXT_FLOATING_POINT | + CONTEXT_EXTENDED_REGISTERS | CONTEXT_DEBUG_REGISTERS; - GetThreadContext (th->h, &th->context); + if (GetThreadContext (th->h, &th->context) == 0) { + DWORD e = GetLastError(); + + if (e == ERROR_INVALID_PARAMETER) { + /* try limited set */ + th->context.ContextFlags = CONTEXT_FULL | + CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS; + if (GetThreadContext (th->h, &th->context) == 0) { + DWORD e = GetLastError(); + printf("GetThreadContext failure %d\n", e); + return; + } + } + } debug_registers_changed = 0; @@ -193,6 +213,12 @@ i386_store_inferior_register (win32_thre collect_register (r, context_offset); } +/* + * The INT 3 instruction is used for x86 platform breakpointing. + */ +static const unsigned char i386_wince_breakpoint = 0xCC; +#define i386_wince_breakpoint_len 1 + struct win32_target_ops the_low_target = { init_registers_i386, sizeof (mappings) / sizeof (mappings[0]), @@ -203,6 +229,6 @@ struct win32_target_ops the_low_target = i386_fetch_inferior_register, i386_store_inferior_register, i386_single_step, - NULL, /* breakpoint */ - 0, /* breakpoint_len */ + &i386_wince_breakpoint, /* breakpoint */ + i386_wince_breakpoint_len, /* breakpoint_len */ }; Index: win32-low.c =================================================================== RCS file: /cvs/src/src/gdb/gdbserver/win32-low.c,v retrieving revision 1.35 diff -u -u -p -r1.35 win32-low.c --- win32-low.c 1 Apr 2009 22:50:24 -0000 1.35 +++ win32-low.c 1 Jul 2009 19:28:15 -0000 @@ -873,14 +873,19 @@ win32_add_one_solib (const char *name, C loaded_dll (buf2, load_addr); } +/* + * Warning : some parts of this function rely on sizeof(WCHAR) == 2 + */ static char * get_image_name (HANDLE h, void *address, int unicode) { - static char buf[(2 * MAX_PATH) + 1]; + static char buf[(2 * MAX_PATH) + 1]; /* here */ DWORD size = unicode ? sizeof (WCHAR) : sizeof (char); char *address_ptr; +#ifndef _WIN32_WCE int len = 0; - char b[2]; + char b[2]; /* here */ +#endif DWORD done; /* Attempt to read the name of the dll that was detected. @@ -903,9 +908,28 @@ get_image_name (HANDLE h, void *address, return NULL; #endif +#ifdef _WIN32_WCE + /* Always unicode */ + /* Assume you can read it all in one go, or otherwise the done variable will + * tell you how far you've read. + */ + WCHAR *wbuf = alloca ((MAX_PATH + 1) * size); + ReadProcessMemory (h, address_ptr, wbuf, MAX_PATH * size, &done); + if (done < 0 || done > MAX_PATH * size) + buf[0] = '\0'; + else { + int n; + n = wcstombs (buf, wbuf, done); + if (n == (size_t)-1) + buf[0] = '\0'; + /* No need to address the length limit case of the wcstombs call, + * buf has been allocated large enough. */ + } + return buf; +#else /* Find the length of the string */ while (ReadProcessMemory (h, address_ptr + len++ * size, &b, size, &done) - && (b[0] != 0 || b[size - 1] != 0) && done == size) + && (b[0] != 0 || b[size - 1] != 0) && done == size) /* here */ continue; if (!unicode) @@ -920,6 +944,7 @@ get_image_name (HANDLE h, void *address, } return buf; +#endif } typedef BOOL (WINAPI *winapi_EnumProcessModules) (HANDLE, HMODULE *, @@ -1365,7 +1390,20 @@ get_child_debug_event (struct target_wai interruption, but high enough so gdbserver doesn't become a bottleneck. */ if (!WaitForDebugEvent (¤t_event, 250)) - return 0; + { + /* + * Sometimes an application will just not start up. + * Detect this here, return in such a way that the loop ends. + */ + DWORD e = GetLastError(); + + if (e == ERROR_PIPE_NOT_CONNECTED) + { + ourstatus->kind = TARGET_WAITKIND_EXITED; + return 1; /* break the loop in our caller */ + } + return 0; + } } gotevent: --=-96TrWzxvAd7UO8yc9YqA--