1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
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;
|