summaryrefslogtreecommitdiff
path: root/devel/gdb/files/commit-3c3ae77e68
diff options
context:
space:
mode:
Diffstat (limited to 'devel/gdb/files/commit-3c3ae77e68')
-rw-r--r--devel/gdb/files/commit-3c3ae77e68156
1 files changed, 156 insertions, 0 deletions
diff --git a/devel/gdb/files/commit-3c3ae77e68 b/devel/gdb/files/commit-3c3ae77e68
new file mode 100644
index 000000000000..bd232d7031a6
--- /dev/null
+++ b/devel/gdb/files/commit-3c3ae77e68
@@ -0,0 +1,156 @@
+commit 3c3ae77e68a9032ef9f174bf6b1cc992b6a4cb35
+Author: Pedro Alves <palves@redhat.com>
+Date: Thu May 4 15:14:37 2017 +0100
+
+ Fix get_core_register_section leak, introduce thread_section_name
+
+ This plugs a leak introduced in the previous change to
+ get_core_register_section, which removed an xfree call that is
+ actually necessary because the 'section_name' local is static.
+
+ From [1] it looks like the reason the variable was made static to
+ begin with, was just "laziness" to avoid having to think about freeing
+ it on every function return path:
+
+ https://sourceware.org/ml/gdb-patches/2005-03/msg00237.html
+
+ The easiest to fix that nowadays is to use a std::string.
+
+ I don't see a need to xstrdup the section name in the single-threaded
+ case though, and also there's more than one place that computes a
+ multi-threaded section name in the same way. So put the section name
+ computation in a wrapper class with state.
+
+ gdb/ChangeLog:
+ 2017-05-04 Pedro Alves <palves@redhat.com>
+
+ * corelow.c (thread_section_name): New class.
+ (get_core_register_section, get_core_siginfo): Use it.
+
+diff --git gdb/corelow.c gdb/corelow.c
+index 2266f2467a..0aff02d4db 100644
+--- gdb/corelow.c
++++ gdb/corelow.c
+@@ -485,6 +485,51 @@ core_detach (struct target_ops *ops, const char *args, int from_tty)
+ printf_filtered (_("No core file now.\n"));
+ }
+
++/* Build either a single-thread or multi-threaded section name for
++ PTID.
++
++ If ptid's lwp member is zero, we want to do the single-threaded
++ thing: look for a section named NAME (as passed to the
++ constructor). If ptid's lwp member is non-zero, we'll want do the
++ multi-threaded thing: look for a section named "NAME/LWP", where
++ LWP is the shortest ASCII decimal representation of ptid's lwp
++ member. */
++
++class thread_section_name
++{
++public:
++ /* NAME is the single-threaded section name. If PTID represents an
++ LWP, then the build section name is "NAME/LWP", otherwise it's
++ just "NAME" unmodified. */
++ thread_section_name (const char *name, ptid_t ptid)
++ {
++ if (ptid.lwp_p ())
++ {
++ m_storage = string_printf ("%s/%ld", name, ptid.lwp ());
++ m_section_name = m_storage.c_str ();
++ }
++ else
++ m_section_name = name;
++ }
++
++ /* Return the computed section name. The result is valid as long as
++ this thread_section_name object is live. */
++ const char *c_str () const
++ { return m_section_name; }
++
++ /* Disable copy. */
++ thread_section_name (const thread_section_name &) = delete;
++ void operator= (const thread_section_name &) = delete;
++
++private:
++ /* Either a pointer into M_STORAGE, or a pointer to the name passed
++ as parameter to the constructor. */
++ const char *m_section_name;
++ /* If we need to build a new section name, this is where we store
++ it. */
++ std::string m_storage;
++};
++
+ /* Try to retrieve registers from a section in core_bfd, and supply
+ them to core_vec->core_read_registers, as the register set numbered
+ WHICH.
+@@ -511,21 +556,15 @@ get_core_register_section (struct regcache *regcache,
+ const char *human_name,
+ int required)
+ {
+- static char *section_name;
+ struct bfd_section *section;
+ bfd_size_type size;
+ char *contents;
+ bool variable_size_section = (regset != NULL
+ && regset->flags & REGSET_VARIABLE_SIZE);
+- ptid_t ptid = regcache_get_ptid (regcache);
+
+- if (ptid_get_lwp (ptid))
+- section_name = xstrprintf ("%s/%ld", name,
+- ptid_get_lwp (ptid));
+- else
+- section_name = xstrdup (name);
++ thread_section_name section_name (name, regcache->ptid ());
+
+- section = bfd_get_section_by_name (core_bfd, section_name);
++ section = bfd_get_section_by_name (core_bfd, section_name.c_str ());
+ if (! section)
+ {
+ if (required)
+@@ -537,13 +576,14 @@ get_core_register_section (struct regcache *regcache,
+ size = bfd_section_size (core_bfd, section);
+ if (size < min_size)
+ {
+- warning (_("Section `%s' in core file too small."), section_name);
++ warning (_("Section `%s' in core file too small."),
++ section_name.c_str ());
+ return;
+ }
+ if (size != min_size && !variable_size_section)
+ {
+ warning (_("Unexpected size of section `%s' in core file."),
+- section_name);
++ section_name.c_str ());
+ }
+
+ contents = (char *) alloca (size);
+@@ -551,7 +591,7 @@ get_core_register_section (struct regcache *regcache,
+ (file_ptr) 0, size))
+ {
+ warning (_("Couldn't read %s registers from `%s' section in core file."),
+- human_name, name);
++ human_name, section_name.c_str ());
+ return;
+ }
+
+@@ -681,18 +721,8 @@ add_to_spuid_list (bfd *abfd, asection *asect, void *list_p)
+ static LONGEST
+ get_core_siginfo (bfd *abfd, gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
+ {
+- asection *section;
+- char *section_name;
+- const char *name = ".note.linuxcore.siginfo";
+-
+- if (ptid_get_lwp (inferior_ptid))
+- section_name = xstrprintf ("%s/%ld", name,
+- ptid_get_lwp (inferior_ptid));
+- else
+- section_name = xstrdup (name);
+-
+- section = bfd_get_section_by_name (abfd, section_name);
+- xfree (section_name);
++ thread_section_name section_name (".note.linuxcore.siginfo", inferior_ptid);
++ asection *section = bfd_get_section_by_name (abfd, section_name.c_str ());
+ if (section == NULL)
+ return -1;
+