From 0ddc85a82cb785cc9f6e8d9ed0ddbf2f6d14ab95 Mon Sep 17 00:00:00 2001 From: Yaakov Selkowitz Date: Mon, 12 Sep 2016 16:11:45 -0500 Subject: cygwin-gdb 7.10.1 --- .gitignore | 1 + ...ow-to-unwind-cygwin-_sigbe-and-sigdelayed.patch | 457 +++++++++++++++++++++ 0002-7.8-windows-nat-cygwin.patch.patch | 139 +++++++ ...ling-for-realpath-failures-in-windows_mak.patch | 52 +++ 7.8-symtab-cygwin.patch | 44 ++ cygwin-gdb.spec | 14 +- sources | 2 +- 7 files changed, 707 insertions(+), 2 deletions(-) create mode 100644 0001-Teach-gdb-how-to-unwind-cygwin-_sigbe-and-sigdelayed.patch create mode 100644 0002-7.8-windows-nat-cygwin.patch.patch create mode 100644 0003-Better-handling-for-realpath-failures-in-windows_mak.patch create mode 100644 7.8-symtab-cygwin.patch diff --git a/.gitignore b/.gitignore index d66b1e3..9491609 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /gdb-7.9.1.tar.xz +/gdb-7.10.1.tar.xz diff --git a/0001-Teach-gdb-how-to-unwind-cygwin-_sigbe-and-sigdelayed.patch b/0001-Teach-gdb-how-to-unwind-cygwin-_sigbe-and-sigdelayed.patch new file mode 100644 index 0000000..9cee767 --- /dev/null +++ b/0001-Teach-gdb-how-to-unwind-cygwin-_sigbe-and-sigdelayed.patch @@ -0,0 +1,457 @@ +From 3b165f5d903053172dfb2182eea98595b73fd8d1 Mon Sep 17 00:00:00 2001 +From: Jon Turney +Date: Tue, 12 Jan 2016 22:49:09 +0000 +Subject: [PATCH 1/3] Teach gdb how to unwind cygwin _sigbe and sigdelayed + frames + +The majority of functions in the cygwin DLL are wrapped by routines which use an +an alternate stack to return via a signal handler if a signal occured while +inside the function. (See [1],[2]) + +At present, these frames cannot be correctly unwound by gdb. There doesn't seem +to currently be a way to correctly describe these frames using DWARF CFI. + +So instead, write a custom unwinder for _sigbe and sigdelayed frames, which gets +the return address from the alternate stack. + +The offset of tls::stackptr from TIB.stacktop is determined by analyzing the +code in _sigbe or sigdelayed. + +This can backtrace from _sigbe and from a sighandler through sigdelayed. + +Implemented for amd64 and i386 + +Issues: + +1. We should detect if we are in the wrapper after the return address has been +popped off the alternate stack, and if so, fetch the return address from the +register it's been popped into. + +2. If there are multiple _sigbe or sigdelayed stack frames to be unwound, this +only unwinds the first one correctly, because we don't unwind the value of the +alternate stack pointer itself. + +This is no worse than currently, when we can't even unwind one of these frame +correctly, but isn't quite correct. + +I guess this could be handled by defining a pseduo-register to track it's value +as we unwind the stack. + +[1] https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;a=blob;f=winsup/cygwin/gendef +[2] https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;a=blob;f=winsup/cygwin/how-signals-work.txt +--- + gdb/amd64-windows-tdep.c | 57 ++++++++++++ + gdb/i386-cygwin-tdep.c | 28 ++++++ + gdb/windows-tdep.c | 237 +++++++++++++++++++++++++++++++++++++++++++++++ + gdb/windows-tdep.h | 21 +++++ + 4 files changed, 343 insertions(+) + +diff --git a/gdb/amd64-windows-tdep.c b/gdb/amd64-windows-tdep.c +index a092298..c9b9d20 100644 +--- a/gdb/amd64-windows-tdep.c ++++ b/gdb/amd64-windows-tdep.c +@@ -1218,11 +1218,68 @@ amd64_windows_auto_wide_charset (void) + return "UTF-16"; + } + ++static const struct insn_pattern amd64_sigbe_bytes[] = { ++ /* movq $-8,%r11 */ ++ { 0x49, 0xff }, ++ { 0xc7, 0xff }, ++ { 0xc3, 0xff }, ++ { 0xf8, 0xff }, ++ { 0xff, 0xff }, ++ { 0xff, 0xff }, ++ { 0xff, 0xff }, ++ /* xaddq %r11,$tls::stackptr(%r10) */ ++ { 0x4d, 0xff }, ++ { 0x0f, 0xff }, ++ { 0xc1, 0xff }, ++ { 0x9a, 0xff }, ++ { 0x00, 0x00 }, /* 4 bytes for tls::stackptr */ ++ { 0x00, 0x00 }, ++ { 0x00, 0x00 }, ++ { 0x00, 0x00 } ++}; ++ ++static const struct insn_pattern amd64_sigdelayed_bytes[] = { ++ /* movq $-8,%r11 */ ++ { 0x49, 0xff }, ++ { 0xc7, 0xff }, ++ { 0xc3, 0xff }, ++ { 0xf8, 0xff }, ++ { 0xff, 0xff }, ++ { 0xff, 0xff }, ++ { 0xff, 0xff }, ++ /* xaddq %r11,$tls::stackptr(%r12) */ ++ { 0x4d, 0xff }, ++ { 0x0f, 0xff }, ++ { 0xc1, 0xff }, ++ { 0x9c, 0xff }, ++ { 0x24, 0xff }, ++ { 0x00, 0x00 }, /* 4 bytes for tls::stackptr */ ++ { 0x00, 0x00 }, ++ { 0x00, 0x00 }, ++ { 0x00, 0x00 } ++}; ++ ++#define COUNT(x) (sizeof(x)/sizeof(x[0])) ++ ++static const struct insn_pattern_sequence amd64_sigbe = ++ { ++ amd64_sigbe_bytes, COUNT(amd64_sigbe_bytes) ++ }; ++ ++static const struct insn_pattern_sequence amd64_sigdelayed = ++ { ++ amd64_sigdelayed_bytes, COUNT(amd64_sigdelayed_bytes) ++ }; ++ + static void + amd64_windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) + { + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ++ cygwin_sigwrapper_frame_unwind_set_sigbe_pattern (&amd64_sigbe); ++ cygwin_sigwrapper_frame_unwind_set_sigdelayed_pattern (&amd64_sigdelayed); ++ frame_unwind_append_unwinder (gdbarch, &cygwin_sigwrapper_frame_unwind); ++ + /* The dwarf2 unwinder (appended very early by i386_gdbarch_init) is + preferred over the SEH one. The reasons are: + - binaries without SEH but with dwarf2 debug info are correcly handled +diff --git a/gdb/i386-cygwin-tdep.c b/gdb/i386-cygwin-tdep.c +index 79ff478..4fc4686 100644 +--- a/gdb/i386-cygwin-tdep.c ++++ b/gdb/i386-cygwin-tdep.c +@@ -26,6 +26,7 @@ + #include "xml-support.h" + #include "gdbcore.h" + #include "inferior.h" ++#include "frame-unwind.h" + + /* Core file support. */ + +@@ -204,11 +205,38 @@ i386_cygwin_auto_wide_charset (void) + return "UTF-16"; + } + ++static const struct insn_pattern i386_sigbe_bytes[] = { ++ /* movl $-4,%eax */ ++ { 0xb8, 0xff }, ++ { 0xfc, 0xff }, ++ { 0xff, 0xff }, ++ { 0xff, 0xff }, ++ { 0xff, 0xff }, ++ /* xadd %eax,$tls::stackptr(%ebx) */ ++ { 0x0f, 0xff }, ++ { 0xc1, 0xff }, ++ { 0x83, 0xff }, ++ { 0x00, 0x00 }, /* 4 bytes for tls::stackptr */ ++ { 0x00, 0x00 }, ++ { 0x00, 0x00 }, ++ { 0x00, 0x00 } ++}; ++ ++#define COUNT(x) (sizeof(x)/sizeof(x[0])) ++ ++static const struct insn_pattern_sequence i386_sigbe = ++ { ++ i386_sigbe_bytes, COUNT(i386_sigbe_bytes) ++ }; ++ + static void + i386_cygwin_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) + { + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ++ cygwin_sigwrapper_frame_unwind_set_sigbe_pattern (&i386_sigbe); ++ frame_unwind_append_unwinder (gdbarch, &cygwin_sigwrapper_frame_unwind); ++ + windows_init_abi (info, gdbarch); + + set_gdbarch_skip_trampoline_code (gdbarch, i386_cygwin_skip_trampoline_code); +diff --git a/gdb/windows-tdep.c b/gdb/windows-tdep.c +index dc4e2e4..352df90 100644 +--- a/gdb/windows-tdep.c ++++ b/gdb/windows-tdep.c +@@ -33,6 +33,7 @@ + #include "complaints.h" + #include "solib.h" + #include "solib-target.h" ++#include "frame-unwind.h" + #include "gdbcore.h" + + struct cmd_list_element *info_w32_cmdlist; +@@ -540,3 +541,239 @@ even if their meaning is unknown."), + isn't another convenience variable of the same name. */ + create_internalvar_type_lazy ("_tlb", &tlb_funcs, NULL); + } ++ ++struct cygwin_sigwrapper_frame_cache ++{ ++ CORE_ADDR sp; ++ CORE_ADDR pc; ++ CORE_ADDR prev_pc; ++ int tlsoffset; ++}; ++ ++/* Return non-zero if the instructions at PC match the series ++ described in PATTERN, or zero otherwise. PATTERN is an array of ++ 'struct insn_pattern' objects, terminated by an entry whose mask is ++ zero. ++ ++ When the match is successful, fill INSN[i] with what PATTERN[i] ++ matched. */ ++static int ++insns_match_pattern (struct gdbarch *gdbarch, CORE_ADDR pc, ++ const struct insn_pattern *pattern, int length, ++ gdb_byte *insn) ++{ ++ int i; ++ CORE_ADDR npc = pc; ++ ++ for (i = 0; i < length; i++) ++ { ++ gdb_byte buf; ++ target_read_memory (npc, &buf, 1); ++ insn[i] = buf; ++ if ((insn[i] & pattern[i].mask) == pattern[i].data) ++ npc += 1; ++ else ++ return 0; ++ } ++ return 1; ++} ++ ++const struct insn_pattern_sequence *sigbe_pattern; ++const struct insn_pattern_sequence *sigdelayed_pattern; ++ ++void cygwin_sigwrapper_frame_unwind_set_sigbe_pattern ( ++ const struct insn_pattern_sequence *pattern) ++{ ++ sigbe_pattern = pattern; ++} ++ ++void cygwin_sigwrapper_frame_unwind_set_sigdelayed_pattern ( ++ const struct insn_pattern_sequence *pattern) ++{ ++ sigdelayed_pattern = pattern; ++} ++ ++static void ++cygwin_sigwrapper_frame_analyze (struct gdbarch *gdbarch, CORE_ADDR start, ++ CORE_ADDR end, int *tlsoffset) ++{ ++ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ++ CORE_ADDR addr; ++ ++ *tlsoffset = 0; ++ ++ for (addr = start; addr < end; addr++) ++ { ++ if (sigbe_pattern) ++ { ++ int len = sigbe_pattern->length; ++ gdb_byte insn[len]; ++ ++ if (insns_match_pattern (gdbarch, addr, sigbe_pattern->pattern, ++ len, insn)) ++ { ++ *tlsoffset = extract_signed_integer (&(insn[len - 4]), 4, ++ byte_order); ++ break; ++ } ++ } ++ ++ if (sigdelayed_pattern) ++ { ++ int len = sigdelayed_pattern->length; ++ gdb_byte insn[len]; ++ ++ if (insns_match_pattern (gdbarch, addr, sigdelayed_pattern->pattern, ++ len, insn)) ++ { ++ *tlsoffset = extract_signed_integer (&(insn[len - 4]), 4, ++ byte_order); ++ break; ++ } ++ } ++ } ++ ++ /* ++ XXX: Perhaps we should also note the address of the xaddq instruction which ++ pops the RA from the sigstack. If PC is after that, we should look in the ++ appropriate register to get the RA, not on the sigstack. ++ */ ++} ++ ++/* Fill THIS_CACHE using the cygwin sigwrapper unwinding data ++ for THIS_FRAME. */ ++ ++static struct cygwin_sigwrapper_frame_cache * ++cygwin_sigwrapper_frame_cache (struct frame_info *this_frame, void **this_cache) ++{ ++ struct gdbarch *gdbarch = get_frame_arch (this_frame); ++ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ++ struct cygwin_sigwrapper_frame_cache *cache = *this_cache; ++ ptid_t ptid; ++ CORE_ADDR thread_local_base; ++ CORE_ADDR stacktop; ++ CORE_ADDR signalstackptr; ++ CORE_ADDR ra; ++ const int len = gdbarch_addr_bit (gdbarch)/8; ++ gdb_byte buf[len]; ++ ++ /* Get current PC and SP. */ ++ cache->pc = get_frame_pc (this_frame); ++ get_frame_register (this_frame, gdbarch_sp_regnum(gdbarch), buf); ++ cache->sp = extract_unsigned_integer (buf, len, byte_order); ++ ++ /* Get address of top of stack from thread information block */ ++ ptid = inferior_ptid; ++ target_get_tib_address (ptid, &thread_local_base); ++ ++ read_memory(thread_local_base + len, buf, len); ++ stacktop = extract_unsigned_integer(buf, len, byte_order); ++ ++ if (frame_debug) ++ fprintf_unfiltered (gdb_stdlog, ++ "cygwin_sigwrapper_frame_prev_register TEB.stacktop=%s\n", ++ paddress (gdbarch, stacktop )); ++ ++ /* Find cygtls, relative to stacktop, and read signalstackptr from cygtls */ ++ read_memory(stacktop + cache->tlsoffset, buf, len); ++ signalstackptr = extract_unsigned_integer(buf, len, byte_order); ++ ++ if (frame_debug) ++ fprintf_unfiltered (gdb_stdlog, ++ "cygwin_sigwrapper_frame_prev_register sigsp=%s\n", ++ paddress (gdbarch, signalstackptr)); ++ ++ /* Read return address from signal stack */ ++ read_memory (signalstackptr - len, buf, len); ++ cache->prev_pc = extract_unsigned_integer (buf, len, byte_order); ++ ++ if (frame_debug) ++ fprintf_unfiltered (gdb_stdlog, ++ "cygwin_sigwrapper_frame_prev_register ra=%s\n", ++ paddress (gdbarch, cache->prev_pc)); ++ ++ return cache; ++} ++ ++static struct value * ++cygwin_sigwrapper_frame_prev_register (struct frame_info *this_frame, void **this_cache, ++ int regnum) ++{ ++ struct gdbarch *gdbarch = get_frame_arch (this_frame); ++ struct cygwin_sigwrapper_frame_cache *cache = ++ cygwin_sigwrapper_frame_cache (this_frame, this_cache); ++ ++ if (frame_debug) ++ fprintf_unfiltered (gdb_stdlog, ++ "cygwin_sigwrapper_frame_prev_register %s for pc=%s\n", ++ gdbarch_register_name (gdbarch, regnum), ++ paddress (gdbarch, cache->prev_pc)); ++ ++ if (regnum == gdbarch_pc_regnum (gdbarch)) ++ return frame_unwind_got_address (this_frame, regnum, cache->prev_pc); ++ ++ return frame_unwind_got_register (this_frame, regnum, regnum); ++} ++ ++static void ++cygwin_sigwrapper_frame_this_id (struct frame_info *this_frame, void **this_cache, ++ struct frame_id *this_id) ++{ ++ *this_id = frame_id_build_unavailable_stack (get_frame_func (this_frame)); ++} ++ ++static int ++cygwin_sigwrapper_frame_sniffer (const struct frame_unwind *self, ++ struct frame_info *this_frame, ++ void **this_cache) ++{ ++ struct gdbarch *gdbarch = get_frame_arch (this_frame); ++ struct cygwin_sigwrapper_frame_cache* cache; ++ const char *name; ++ int tlsoffset; ++ CORE_ADDR start, end; ++ ++ CORE_ADDR pc = get_frame_pc (this_frame); ++ find_pc_partial_function (pc, &name, &start, &end); ++ ++ if (!name) ++ return 0; ++ ++ if ((strcmp(name, "_sigbe") != 0) && (strcmp(name, "__sigbe") != 0) && ++ (strcmp(name, "sigdelayed") != 0) && (strcmp(name, "_sigdelayed") != 0)) ++ return 0; ++ ++ if (frame_debug) ++ fprintf_unfiltered (gdb_stdlog, ++ "cygwin_sigwrapper_frame_sniffer name=%s, start=%s, end=%s\n", ++ name, paddress (gdbarch, start), paddress (gdbarch, end)); ++ ++ cygwin_sigwrapper_frame_analyze(gdbarch, start, end, &tlsoffset); ++ if (tlsoffset == 0) ++ return 0; ++ ++ if (frame_debug) ++ fprintf_unfiltered (gdb_stdlog, ++ "cygwin_sigwrapper_frame_sniffer sigstackptroffset=%x\n", ++ tlsoffset); ++ ++ cache = FRAME_OBSTACK_ZALLOC (struct cygwin_sigwrapper_frame_cache); ++ cache->tlsoffset = tlsoffset; ++ ++ *this_cache = cache; ++ cygwin_sigwrapper_frame_cache (this_frame, this_cache); ++ ++ return 1; ++} ++ ++/* Cygwin sigwapper unwinder. */ ++ ++const struct frame_unwind cygwin_sigwrapper_frame_unwind = ++{ ++ NORMAL_FRAME, ++ default_frame_unwind_stop_reason, ++ &cygwin_sigwrapper_frame_this_id, ++ &cygwin_sigwrapper_frame_prev_register, ++ NULL, ++ &cygwin_sigwrapper_frame_sniffer ++}; +diff --git a/gdb/windows-tdep.h b/gdb/windows-tdep.h +index e1c34c2..b16a64a 100644 +--- a/gdb/windows-tdep.h ++++ b/gdb/windows-tdep.h +@@ -32,4 +32,25 @@ extern void windows_xfer_shared_library (const char* so_name, + + extern void windows_init_abi (struct gdbarch_info info, + struct gdbarch *gdbarch); ++ ++extern const struct frame_unwind cygwin_sigwrapper_frame_unwind; ++ ++/* An instruction to match. */ ++struct insn_pattern ++{ ++ gdb_byte data; /* See if it matches this.... */ ++ gdb_byte mask; /* ... with this mask. */ ++}; ++ ++struct insn_pattern_sequence ++{ ++ const struct insn_pattern *pattern; ++ int length; ++}; ++ ++extern void cygwin_sigwrapper_frame_unwind_set_sigbe_pattern( ++ const struct insn_pattern_sequence *pattern); ++extern void cygwin_sigwrapper_frame_unwind_set_sigdelayed_pattern( ++ const struct insn_pattern_sequence *pattern); ++ + #endif +-- +2.6.2 + diff --git a/0002-7.8-windows-nat-cygwin.patch.patch b/0002-7.8-windows-nat-cygwin.patch.patch new file mode 100644 index 0000000..8f14555 --- /dev/null +++ b/0002-7.8-windows-nat-cygwin.patch.patch @@ -0,0 +1,139 @@ +From 6ff2426819cc3cfb9cf4a12ed733a580f25ee0e9 Mon Sep 17 00:00:00 2001 +From: Jon Turney +Date: Tue, 12 Jan 2016 22:26:26 +0000 +Subject: [PATCH 2/3] 7.8-windows-nat-cygwin.patch + +Remaining parts of 7.8-windows-nat-cygwin.patch not yet upstream. + +Signal changes: + +* Replace have_saved_context with signal_thread_id throughout, and store the +thread id in it + +* In thread_rec(), only use the signal saved context if we are retrieving the +context for the correct thread. + +* Clear ContextFlags in the signal saved context so we never attempt to restore +it to the inferior + +Since the signal context is the context which will be restored after any signal +handler has been run, to resume to it skips over the actual signal delivery. + +(Unfortunately, this isn't quite right. If GDB decides it needs to single-step +after continuing by setting FLAG_TRACE_BIT, we must alter the inferior state. So +we potentially need to have both the signal saved context, and the actual +context for the thread. Which is not a straightforward change to make.) + +Unrelated changes: + +* An unclear change for detecting if it's an unexpected Cygwin message. Just +checking for a leading 'cYg' should be enough? + +* Cast DWORD thread_id to int before returning it from get_windows_event. +(I don't think this is needed. If DWORD->int is a narrowing conversion, we +have other problems...) + +* In one place, clarify that thread_rec()'s second parameter is a bool flag. +(This should be done everywhere, or not) +--- + gdb/windows-nat.c | 28 ++++++++++++++++++---------- + 1 file changed, 18 insertions(+), 10 deletions(-) + +diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c +index 2f674b6..0d145ac 100644 +--- a/gdb/windows-nat.c ++++ b/gdb/windows-nat.c +@@ -118,8 +118,7 @@ static COORD WINAPI (*GetConsoleFontSize) (HANDLE, DWORD); + # define bad_GetModuleFileNameEx bad_GetModuleFileNameExW + #endif + +-static int have_saved_context; /* True if we've saved context from a +- cygwin signal. */ ++static DWORD signal_thread_id; /* Non-zero if we saved context. */ + static CONTEXT saved_context; /* Containes the saved context from a + cygwin signal. */ + +@@ -301,7 +300,8 @@ thread_rec (DWORD id, int get_context) + { + if (!th->suspended && get_context) + { +- if (get_context > 0 && id != current_event.dwThreadId) ++ if (get_context > 0 && id != current_event.dwThreadId ++ && id != signal_thread_id) + { + if (SuspendThread (th->h) == (DWORD) -1) + { +@@ -436,7 +436,7 @@ do_windows_fetch_inferior_registers (struct regcache *regcache, int r) + if (current_thread->reload_context) + { + #ifdef __CYGWIN__ +- if (have_saved_context) ++ if (signal_thread_id) + { + /* Lie about where the program actually is stopped since + cygwin has informed us that we should consider the signal +@@ -444,7 +444,7 @@ do_windows_fetch_inferior_registers (struct regcache *regcache, int r) + "saved_context. */ + memcpy (¤t_thread->context, &saved_context, + __COPY_CONTEXT_SIZE); +- have_saved_context = 0; ++ signal_thread_id = 0; + } + else + #endif +@@ -819,7 +819,11 @@ handle_output_debug_string (struct target_waitstatus *ourstatus) + else if (!startswith (s, _CYGWIN_SIGNAL_STRING)) + { + #ifdef __CYGWIN__ +- if (!startswith (s, "cYg")) ++ /* This looks like this is supposed to ignore all other expected Cygwin ++ debug output (e.g. handle and strace output), but isn't quite right as ++ strace output might be indicated by any 8 digit hex address. */ ++ if (!startswith (s, "cYg") || (strncmp (s + 3, "FFFFFFFF", 8) != 0 ++ && strncmp (s + 3, "std", 3) != 0)) + #endif + { + char *p = strchr (s, '\0'); +@@ -858,7 +862,12 @@ handle_output_debug_string (struct target_waitstatus *ourstatus) + &saved_context, + __COPY_CONTEXT_SIZE, &n) + && n == __COPY_CONTEXT_SIZE) +- have_saved_context = 1; ++ { ++ signal_thread_id = retval; ++ saved_context.ContextFlags = 0; /* Don't attempt to call SetContext */ ++ } ++ else ++ retval = 0; + } + } + #endif +@@ -1343,7 +1352,6 @@ get_windows_debug_event (struct target_ops *ops, + event_code = current_event.dwDebugEventCode; + ourstatus->kind = TARGET_WAITKIND_SPURIOUS; + th = NULL; +- have_saved_context = 0; + + switch (event_code) + { +@@ -1521,7 +1529,7 @@ get_windows_debug_event (struct target_ops *ops, + } + + out: +- return thread_id; ++ return (int) thread_id; + } + + /* Wait for interesting events to occur in the target process. */ +@@ -2467,7 +2475,7 @@ windows_get_tib_address (struct target_ops *self, + { + windows_thread_info *th; + +- th = thread_rec (ptid_get_tid (ptid), 0); ++ th = thread_rec (ptid_get_tid (ptid), FALSE); + if (th == NULL) + return 0; + +-- +2.6.2 + diff --git a/0003-Better-handling-for-realpath-failures-in-windows_mak.patch b/0003-Better-handling-for-realpath-failures-in-windows_mak.patch new file mode 100644 index 0000000..4a74ce1 --- /dev/null +++ b/0003-Better-handling-for-realpath-failures-in-windows_mak.patch @@ -0,0 +1,52 @@ +From cc58015ddf527b4344183c4c3e2dcc4333457011 Mon Sep 17 00:00:00 2001 +From: Jon Turney +Date: Wed, 13 Jan 2016 18:27:48 +0000 +Subject: [PATCH 3/3] Better handling for realpath() failures in + windows_make_so() on Cygwin + +Fix a memory leak which would occur in the case when the result of realpath() is +greater than or equal to SO_NAME_MAX_PATH_SIZE. + +Distinguish between realpath() failing (returning NULL), and returning a path +longer than SO_NAME_MAX_PATH_SIZE + +Warn rather than stopping with an error in those cases. + +Original patch from Tim Chick. Memory leak fix by Corinna Vinschen. +--- + gdb/windows-nat.c | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c +index 0d145ac..2e26286 100644 +--- a/gdb/windows-nat.c ++++ b/gdb/windows-nat.c +@@ -619,13 +619,22 @@ windows_make_so (const char *name, LPVOID load_addr) + else + { + char *rname = realpath (name, NULL); +- if (rname && strlen (rname) < SO_NAME_MAX_PATH_SIZE) ++ if (rname) + { +- strcpy (so->so_name, rname); ++ if (strlen (rname) < SO_NAME_MAX_PATH_SIZE) ++ strcpy (so->so_name, rname); ++ else ++ { ++ warning (_("dll path \"%s\" too long"), rname); ++ strcpy (so->so_name, so->so_original_name); ++ } + free (rname); + } + else +- error (_("dll path too long")); ++ { ++ warning (_("dll path for \"%s\" can not be evaluated"), name); ++ strcpy (so->so_name, so->so_original_name); ++ } + } + /* Record cygwin1.dll .text start/end. */ + p = strchr (so->so_name, '\0') - (sizeof ("/cygwin1.dll") - 1); +-- +2.6.2 + diff --git a/7.8-symtab-cygwin.patch b/7.8-symtab-cygwin.patch new file mode 100644 index 0000000..6af82ba --- /dev/null +++ b/7.8-symtab-cygwin.patch @@ -0,0 +1,44 @@ +See https://sourceware.org/ml/gdb-patches/2002-03/msg00557.html + +--- origsrc/gdb-7.8/gdb/symtab.c 2014-07-29 14:37:42.000000000 +0200 ++++ src/gdb-7.8/gdb/symtab.c 2014-08-04 12:04:47.173108524 +0200 +@@ -641,6 +641,39 @@ symbol_find_demangled_name (struct gener + { + char *demangled = NULL; + ++ /* On Windows, some functions use the `stdcall' calling convention, ++ in which the callee is expected to pop the arguments off the ++ stack. Normally, the caller takes care of this, because only the ++ caller knows how many arguments it really passed. To avoid ++ confusion, the linker symbols for `stdcall' functions have names ++ with a suffix "@N" attached to them, where "N" is the number of ++ bytes they'll pop. That way, if a caller thinks some `stdcall' ++ function `foo' expects M argument bytes, but the definition of ++ `foo' expects N argument bytes, N != M, then the call will be a ++ reference to `foo@M', but the definition will have a linker ++ symbol `foo@N', and you'll get a link-time `symbol not found' ++ error, instead of a crash at run-time. ++ ++ (Note how this fails to address calls through function pointers, ++ since the byte count isn't part of the function pointer's type. ++ Go, Microsoft!) ++ ++ Whatever. But our demangler doesn't like that '@N' suffix, so we ++ need to strip it off. */ ++ if (1) ++ { ++ char *arg_byte_suffix = strchr (mangled, '@'); ++ if (arg_byte_suffix) ++ { ++ int prefix_len = arg_byte_suffix - mangled; ++ char *mangled_sans_suffix = alloca (prefix_len + 1); ++ memcpy (mangled_sans_suffix, mangled, prefix_len); ++ mangled_sans_suffix[prefix_len] = '\0'; ++ ++ mangled = mangled_sans_suffix; ++ } ++ } ++ + if (gsymbol->language == language_unknown) + gsymbol->language = language_auto; + diff --git a/cygwin-gdb.spec b/cygwin-gdb.spec index 9d1ba5f..407e3dd 100644 --- a/cygwin-gdb.spec +++ b/cygwin-gdb.spec @@ -1,12 +1,17 @@ Name: cygwin-gdb -Version: 7.9.1 +Version: 7.10.1 Release: 1%{?dist} Summary: Cygwin GNU debugger License: GPLv3+ Group: Development/Utilities URL: http://www.gnu.org/software/gdb/ + Source0: ftp://sourceware.org/pub/gdb/releases/gdb-%{version}.tar.xz +Patch0: 7.8-symtab-cygwin.patch +Patch1: 0001-Teach-gdb-how-to-unwind-cygwin-_sigbe-and-sigdelayed.patch +Patch2: 0002-7.8-windows-nat-cygwin.patch.patch +Patch3: 0003-Better-handling-for-realpath-failures-in-windows_mak.patch BuildRequires: expat-devel BuildRequires: ncurses-devel @@ -52,6 +57,10 @@ using a gdbserver(1) instance on a Cygwin machine to run the executable. %prep %setup -q -n gdb-%{version} +%patch0 -p2 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 %build @@ -127,6 +136,9 @@ rm -f $RPM_BUILD_ROOT%{_mandir}/man1/*gdbserver* %changelog +* Mon Sep 12 2016 Yaakov Selkowitz - 7.10.1-1 +- new version + * Thu Aug 20 2015 Yaakov Selkowitz - 7.9.1-1 - New version with split support for Cygwin 32- and 64-bit toolchains diff --git a/sources b/sources index c93b64d..9cba2ff 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -35374c77a70884eb430c97061053a36e gdb-7.9.1.tar.xz +39e654460c9cdd80200a29ac020cfe11 gdb-7.10.1.tar.xz -- cgit