From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from sonic304-21.consmr.mail.ir2.yahoo.com (sonic304-21.consmr.mail.ir2.yahoo.com [77.238.179.146]) by sourceware.org (Postfix) with ESMTPS id 53D0C385DC0C for ; Wed, 29 Apr 2020 10:54:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 53D0C385DC0C X-YMail-OSG: MgT25VsVM1m1LXIKg8HqDaT52hThGDq23ieLiprpsTEq33dXL4pkRTTltxo.Tq1 fLx0nvIemN5.9POAsbmRIpi4DFllwq9CaXv5cFO_3R8XM.eJgu9PAgy4SToaiZrUWISLb7THiv0w k.WFwOZZgih.iiznvFrfxYJP8skgYkIeNfkBfm8UeiUIMgEND.UVwZiEHwRJ_Mgxrrl8BwqGgUH8 fo29JclNX0oiQGVTRB.bhK2aC0YjMiXIavW3p7E.TS_7kg7_2LNSpH749BEg__v2OiVK959motMq uQcGEflwbnYbHOYeEYTuIb.wwREnW_QbI0iZubIQ1hx_YqcRW_L19q0wynKdmGGgToHa8YDmXNAU hCVqhdYgPMqsGV1gp7MJItU7o3J.rmTY0BSt.7odVl.c4p6MqSkrm63GG8hLJt8Q5oVSk4kj.GbQ NPJaM8YWqN1ql7NvyJrs6dDvqrnt_vvaUXZYRSC4LHuJ101kmcnZp.LdDENCYoHv0BGq._G2gY6h BGV.8uBjhitx4H8ilyy.4vxX_LhbnIvH8PUasj7dxXhiAJBfGyG4JK76OpTYBvDn6XFstvlgtpZ1 QhtyqU4rI2Bqt0kwYNJu8KcJwAuTBkDoLDl4CoZyJ4fwVZv8.ycuTUfLYKtmJj3V2oV.YE_sI4Gs czPRo3W4VgdH7khxEig8J1kcURDeBnZmyhH6pNU9URruSJGApvU6LlY0oM7qSCOugG4960rt7v7D eppRQvs0tTltIPOXtQlvsyMFiKrX73Se9qFuY34XHSYbv2ymJ1zuwnnzSxP.XR8Ek.qmlm2p.FOV C1QmqV7PgY5UMNV9sDl0ZBhX_XmGwgCr_GmyqG_08sQIIkppekMVq43kh9CL4OnfllBNJE1nRYsq wU4VDum0AcBZIiNIQTUFyp.jtxD8ElEdBFlvO0C49qU7vv.MzRRxb_RmzSEITXvIStVXia9uK.Gw G6AU4Qpr4Slg4obif_1lIueDja8.23meMMrf33l.YMUwEQFoDNetM8oo22nx23dGpb6fDEMpMIsM Ui1YgpmngfxCRirDQtexa0CozmmF1lMEOmR8XFSTcHsFV8DJmhoTgInnTECLc6_Q_trcQQoWB4M_ GjGsT2wpmzuItKW9HjXIRtYV26OLwS2IaFsQMAV6qs288NRolGWxeEVVzvecTlIPX5lnzR7wZPHq 3E9oNtRmf7g1Trg4JBpTYpe.9JrFTuF0E2K_VZaxFrnhbM4Txhrv8Nh2SC1dwjDpUSLz512r5sPT 234B.s7A.ItGGKy4jimnCnFTKZw5WiPhKShfjI1a6s0THcqYqfHjq8BdVjpYpngHCwCZYhBvTcCQ _LNlCeLUDfy4kEiFvelMZfp7Tzb6MzYjpHoDrRq556j1V2UbfGBOPYpsqMmWKB.g5IozpOYj_fuN vRccKU5pa5ZapOPZATyJfyYpn9i9.Txz96KcmUXCM2V3hLg-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic304.consmr.mail.ir2.yahoo.com with HTTP; Wed, 29 Apr 2020 10:54:30 +0000 Date: Wed, 29 Apr 2020 10:54:25 +0000 (UTC) From: Hannes Domani To: Gdb-patches Message-ID: <471105047.4011567.1588157665165@mail.yahoo.com> In-Reply-To: <7ec0c0b7-5425-d766-326b-9d5b13b755b4@simark.ca> References: <20200427133416.9314-1-ssbssa.ref@yahoo.de> <20200427133416.9314-1-ssbssa@yahoo.de> <7ec0c0b7-5425-d766-326b-9d5b13b755b4@simark.ca> Subject: Re: [PATCH v2] Implement debugging of WOW64 processes in gdbserver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Mailer: WebService/1.1.15756 YMailNorrin Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0 X-Spam-Status: No, score=-16.5 required=5.0 tests=BAYES_00, BODY_8BITS, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 29 Apr 2020 10:54:35 -0000 Am Dienstag, 28. April 2020, 17:53:15 MESZ hat Simon Marchi Folgendes geschrieben: > On 2020-04-27 9:34 a.m., Hannes Domani via Gdb-patches wrote: > > @@ -496,7 +601,7 @@ i386_win32_set_pc (struct regcache *regcache, CORE_= ADDR pc) > > > >=C2=A0 struct win32_target_ops the_low_target =3D { > >=C2=A0=C2=A0=C2=A0 i386_arch_setup, > > -=C2=A0 sizeof (mappings) / sizeof (mappings[0]), > > +=C2=A0 i386_win32_num_regs, > >=C2=A0=C2=A0=C2=A0 i386_initial_stuff, > >=C2=A0=C2=A0=C2=A0 i386_get_thread_context, > >=C2=A0=C2=A0=C2=A0 i386_prepare_to_resume, > > diff --git a/gdbserver/win32-low.cc b/gdbserver/win32-low.cc > > index 5a6f0df39f..d3fc31914d 100644 > > --- a/gdbserver/win32-low.cc > > +++ b/gdbserver/win32-low.cc > > @@ -88,15 +88,32 @@ static int soft_interrupt_requested =3D 0; > >=C2=A0=C2=A0=C2=A0 by suspending all the threads.=C2=A0 */ > >=C2=A0 static int faked_breakpoint =3D 0; > > > > +#ifdef __x86_64__ > > +bool wow64_process =3D false; > > +#endif > > + > >=C2=A0 const struct target_desc *win32_tdesc; > > +#ifdef __x86_64__ > > +const struct target_desc *wow64_win32_tdesc; > > +#endif > > > > -#define NUM_REGS (the_low_target.num_regs) > > +#define NUM_REGS (the_low_target.num_regs ()) > > > >=C2=A0 typedef BOOL (WINAPI *winapi_DebugActiveProcessStop) (DWORD dwPro= cessId); > >=C2=A0 typedef BOOL (WINAPI *winapi_DebugSetProcessKillOnExit) (BOOL Kil= lOnExit); > >=C2=A0 typedef BOOL (WINAPI *winapi_DebugBreakProcess) (HANDLE); > >=C2=A0 typedef BOOL (WINAPI *winapi_GenerateConsoleCtrlEvent) (DWORD, DW= ORD); > > > > +#ifdef __x86_64__ > > +typedef DWORD (WINAPI *winapi_Wow64SuspendThread) (HANDLE); > > +typedef BOOL (WINAPI *winapi_Wow64SetThreadContext) (HANDLE, > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 const WOW64_CONTEXT *); > > + > > +static winapi_Wow64SuspendThread win32_Wow64SuspendThread; > > win32_Wow64SuspendThread is never actually used, is this expected? Well, in this case, kinda. I only noticed afterwards that the same Wow64SuspendThread was unused in th= e gdb equivalent, because unexpectedly, SuspendThread does work (at least on my PC). But I will remove it from this patch, and will try to fix it for both gdb & gdbserver with a later patch. > > @@ -195,7 +231,14 @@ child_add_thread (DWORD pid, DWORD tid, HANDLE h, = void *tlb) > >=C2=A0=C2=A0=C2=A0 if ((th =3D thread_rec (ptid, DONT_INVALIDATE_CONTEXT= ))) > >=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return th; > > > > -=C2=A0 th =3D new windows_thread_info (tid, h, (CORE_ADDR) (uintptr_t)= tlb); > > +=C2=A0 CORE_ADDR base =3D (CORE_ADDR) (uintptr_t) tlb; > > +#ifdef __x86_64__ > > +=C2=A0 /* For WOW64 processes, this is actually the pointer to the 64b= it TIB, > > +=C2=A0=C2=A0=C2=A0 and the 32bit TIB is exactly 2 pages after it.=C2= =A0 */ > > Do you have a reference for this, ideally from MSDN?=C2=A0 If so, it woul= d be nice to > include the link in the comment. Sadly no, I could find no official document for this. There is an alternative way for to get the 32bit TIB, via the address at offset 0 of the 64bit TIB: https://docs.microsoft.com/en-us/windows/win32/debug/thread-environment-blo= ck--debugging-notes- But even here it is mentioned that this may change in later Windows version= s. > > +=C2=A0 if (wow64_process) > > +=C2=A0=C2=A0=C2=A0 base +=3D 0x2000; > > Could you make it a PAGE_SIZE macro, and wirte `2 * PAGE_SIZE` here?=C2= =A0 It would > make it more obvious that it matches the comment above. OK. > > +#endif > > +=C2=A0 th =3D new windows_thread_info (tid, h, base); > > > >=C2=A0=C2=A0=C2=A0 add_thread (ptid, th); > > > > @@ -345,8 +388,27 @@ do_initial_child_stuff (HANDLE proch, DWORD pid, i= nt attached) > > > >=C2=A0=C2=A0=C2=A0 memset (¤t_event, 0, sizeof (current_event)); > > > > +#ifdef __x86_64__ > > +=C2=A0 BOOL wow64; > > +=C2=A0 if (IsWow64Process (proch, &wow64)) > > +=C2=A0=C2=A0=C2=A0 wow64_process =3D wow64; > > If this function fails, it means we couldn't get the information we reque= sted.=C2=A0 In > this case, I think we should error out, because we can't continue reliabl= y.=C2=A0 So, > something like: > > BOOL wow64; > if (!IsWow64Process (proch, &wow64_process)) >=C2=A0=C2=A0 { >=C2=A0=C2=A0=C2=A0=C2=A0 // Call error() with a message formatted from Get= LastError(). >=C2=A0=C2=A0 } OK. > > @@ -1096,13 +1197,53 @@ win32_add_all_dlls (void) > >=C2=A0=C2=A0=C2=A0 if (!DllHandle) > >=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return; > > > > -=C2=A0 ok =3D (*win32_EnumProcessModules) (current_process_handle, > > -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 DllHandle, > > -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 cbNeeded, > > -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 &cbNeeded); > > +#ifdef __x86_64__ > > +=C2=A0 if (wow64_process) > > +=C2=A0=C2=A0=C2=A0 ok =3D (*win32_EnumProcessModulesEx) (current_proce= ss_handle, > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 DllHandle, > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 cbNeeded, > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 &cbNeeded, > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 LIST_MODULES_32BIT); > > +=C2=A0 else > > +#endif > > +=C2=A0=C2=A0=C2=A0 ok =3D (*win32_EnumProcessModules) (current_process= _handle, > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 DllHandle, > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 cbNeeded, > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 &cbNeeded); > >=C2=A0=C2=A0=C2=A0 if (!ok) > >=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return; > > > > +=C2=A0 char system_dir[MAX_PATH]; > > +=C2=A0 char syswow_dir[MAX_PATH]; > > +=C2=A0 size_t system_dir_len =3D 0; > > +=C2=A0 bool convert_syswow_dir =3D false; > > +#ifdef __x86_64__ > > +=C2=A0 if (wow64_process) > > +#endif > > +=C2=A0=C2=A0=C2=A0 { > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 /* This fails on 32bit Windows because = it has no SysWOW64 directory, > > +=C2=A0=C2=A0=C2=A0 and in this case a path conversion isn't necessary.= =C2=A0 */ > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 UINT len =3D GetSystemWow64DirectoryA (= syswow_dir, sizeof (syswow_dir)); > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (len > 0) > > +=C2=A0=C2=A0=C2=A0 { > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 /* Check that we have passed a large en= ough buffer.=C2=A0 */ > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 gdb_assert (len < sizeof (syswow_dir)); > > + > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 len =3D GetSystemDirectoryA (system_dir= , sizeof (system_dir)); > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 /* Error check.=C2=A0 */ > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 gdb_assert (len !=3D 0); > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 /* Check that we have passed a large en= ough buffer.=C2=A0 */ > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 gdb_assert (len < sizeof (system_dir)); > > + > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 strcat (system_dir, "\\"); > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 strcat (syswow_dir, "\\"); > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 system_dir_len =3D strlen (system_dir); > > + > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 convert_syswow_dir =3D true; > > +=C2=A0=C2=A0=C2=A0 } > > + > > +=C2=A0=C2=A0=C2=A0 } > > Since this is copied from gdb/windows-nat.c, it would be nice to factor i= t > out (as well as the small snippet below), so it can be shared.=C2=A0 Othe= rwise, > if we make a fix to one, we'll most likely forget to fix the other. > > The shared versions would go into gdb/nat/windows-nat.c. There might be even more code that can be shared now, I planned to do this with a later patch. > > + > >=C2=A0=C2=A0=C2=A0 for (i =3D 1; i < ((size_t) cbNeeded / sizeof (HMODUL= E)); i++) > >=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 { > >=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 MODULEINFO mi; > > @@ -1118,7 +1259,22 @@ win32_add_all_dlls (void) > >=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 dll_name, > >=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 MAX_PATH) =3D=3D 0) > >=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 continue; > > -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 win32_add_one_solib (dll_name, (CORE_AD= DR) (uintptr_t) mi.lpBaseOfDll); > > + > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const char *name =3D dll_name; > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 /* Convert the DLL path of 32bit proces= ses returned by > > +=C2=A0=C2=A0=C2=A0 GetModuleFileNameEx from the 64bit system directory= to the > > +=C2=A0=C2=A0=C2=A0 32bit syswow64 directory if necessary.=C2=A0 */ > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 std::string syswow_dll_path; > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (convert_syswow_dir > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 && strncasecmp (dll_name, system_dir, s= ystem_dir_len) =3D=3D 0 > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 && strchr (dll_name + system_dir_len, '= \\') =3D=3D nullptr) > > +=C2=A0=C2=A0=C2=A0 { > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 syswow_dll_path =3D syswow_dir; > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 syswow_dll_path +=3D dll_name + system_= dir_len; > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 name =3D syswow_dll_path.c_str(); > > +=C2=A0=C2=A0=C2=A0 } > > + > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 win32_add_one_solib (name, (CORE_ADDR) = (uintptr_t) mi.lpBaseOfDll); > >=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 } > >=C2=A0 } > >=C2=A0 #endif > > @@ -1221,8 +1377,10 @@ maybe_adjust_pc () > >=C2=A0=C2=A0=C2=A0 th->stopped_at_software_breakpoint =3D false; > > > >=C2=A0=C2=A0=C2=A0 if (current_event.dwDebugEventCode =3D=3D EXCEPTION_D= EBUG_EVENT > > -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 && (current_event.u.Exception.Exception= Record.ExceptionCode > > -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 =3D=3D EXCEPTION_BREAKPOINT) > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 && ((current_event.u.Exception.Exceptio= nRecord.ExceptionCode > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 =3D=3D EXCEPTION_BREAKPOINT) > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 || (current_event.u.Exception.Exception= Record.ExceptionCode > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 =3D=3D STATUS_W= X86_BREAKPOINT)) > >=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 && child_initialization_done) > >=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 { > >=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 th->stopped_at_software_break= point =3D true; > > @@ -1684,13 +1842,34 @@ win32_process_target::qxfer_siginfo (const char= *annex, > >=C2=A0=C2=A0=C2=A0 if (readbuf =3D=3D nullptr) > >=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return -1; > > > > -=C2=A0 if (offset > sizeof (siginfo_er)) > > +=C2=A0 char *buf =3D (char *) &siginfo_er; > > +=C2=A0 size_t bufsize =3D sizeof (siginfo_er); > > + > > +#ifdef __x86_64__ > > +=C2=A0 EXCEPTION_RECORD32 er32; > > +=C2=A0 if (wow64_process) > > +=C2=A0=C2=A0=C2=A0 { > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 buf =3D (char *) &er32; > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 bufsize =3D sizeof (er32); > > + > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 er32.ExceptionCode =3D siginfo_er.Excep= tionCode; > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 er32.ExceptionFlags =3D siginfo_er.Exce= ptionFlags; > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 er32.ExceptionRecord =3D (uintptr_t) si= ginfo_er.ExceptionRecord; > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 er32.ExceptionAddress =3D (uintptr_t) s= iginfo_er.ExceptionAddress; > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 er32.NumberParameters =3D siginfo_er.Nu= mberParameters; > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 int i; > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 for (i =3D 0; i < EXCEPTION_MAXIMUM_PAR= AMETERS; i++) > > +=C2=A0=C2=A0=C2=A0 er32.ExceptionInformation[i] =3D siginfo_er.Excepti= onInformation[i]; > > +=C2=A0=C2=A0=C2=A0 } > > +#endif > > + > > +=C2=A0 if (offset > bufsize) > >=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return -1; > > > > -=C2=A0 if (offset + len > sizeof (siginfo_er)) > > -=C2=A0=C2=A0=C2=A0 len =3D sizeof (siginfo_er) - offset; > > +=C2=A0 if (offset + len > bufsize) > > +=C2=A0=C2=A0=C2=A0 len =3D bufsize - offset; > > > > -=C2=A0 memcpy (readbuf, (char *) &siginfo_er + offset, len); > > +=C2=A0 memcpy (readbuf, buf + offset, len); > > > >=C2=A0=C2=A0=C2=A0 return len; > >=C2=A0 } > > @@ -1760,4 +1939,11 @@ initialize_low (void) > >=C2=A0 { > >=C2=A0=C2=A0=C2=A0 set_target_ops (&the_win32_target); > >=C2=A0=C2=A0=C2=A0 the_low_target.arch_setup (); > > + > > +#ifdef __x86_64__ > > +=C2=A0 HMODULE dll =3D GetModuleHandle (_T("KERNEL32.DLL")); > > +=C2=A0 win32_Wow64SuspendThread =3D GETPROCADDRESS (dll, Wow64SuspendT= hread); > > +=C2=A0 win32_Wow64GetThreadContext =3D GETPROCADDRESS (dll, Wow64GetTh= readContext); > > +=C2=A0 win32_Wow64SetThreadContext =3D GETPROCADDRESS (dll, Wow64SetTh= readContext); > > Why do we need to get these functions like this, instead of just calling = them? These functions are not available on WinXP, and the extra check for them was actually the reason of this v2: +=C2=A0 if (wow64_process +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 && (win32_Wow64SuspendThread =3D=3D nullptr +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 || win32_Wow64GetThreadContext =3D=3D nullp= tr +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 || win32_Wow64SetThreadContext =3D=3D nullp= tr)) +=C2=A0=C2=A0=C2=A0 error ("WOW64 debugging is not supported on this system= .\n"); Hannes