aboutsummaryrefslogtreecommitdiff
path: root/gdb/printcmd.c
diff options
context:
space:
mode:
authorAndrew Burgess <aburgess@redhat.com>2023-05-31 20:57:01 +0100
committerAndrew Burgess <aburgess@redhat.com>2023-07-07 15:20:28 +0100
commit7d8708653dc05075b926a61303abd96c3f746e25 (patch)
tree3c870846cc8569562128ffff7c82d8cc0128bc76 /gdb/printcmd.c
parent1a36815e2f1ad39acf894660759cf1a0bef39fcc (diff)
downloadgdb-7d8708653dc05075b926a61303abd96c3f746e25.zip
gdb-7d8708653dc05075b926a61303abd96c3f746e25.tar.gz
gdb-7d8708653dc05075b926a61303abd96c3f746e25.tar.bz2
gdb: remove last alloca call from printcmd.c
This commit removes the last alloca call from printcmd.c. This is similar to the patches I originally posted here: https://inbox.sourceware.org/gdb-patches/cover.1677533215.git.aburgess@redhat.com/ However, this change was not included in that original series. The original series received push back because it was thought that replacing alloca with a C++ container type would introduce unnecessary malloc/free overhead. However, in this case we are building a string, and (at least for GCC), the std::string type has a small string optimisation, where small strings are stored on the stack. And in this case we are building what will usually be a very small string, we're just constructing a printf format specifier for a hex value, so it'll be something like '%#x' -- though it could also have a width in there too -- but still, it should normally fit within GCCs small string buffer. So, in this commit, I propose replacing the use of alloca with a std::string. This shouldn't result (normally) in any additional malloc or free calls, so should be similar in performance to the original approach. There should be no user visible differences after this commit.
Diffstat (limited to 'gdb/printcmd.c')
-rw-r--r--gdb/printcmd.c30
1 files changed, 13 insertions, 17 deletions
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 31f87c7..0535128 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -2653,62 +2653,58 @@ printf_pointer (struct ui_file *stream, const char *format,
modifier for %p is a width; extract that, and then
handle %p as glibc would: %#x or a literal "(nil)". */
- const char *p;
- char *fmt, *fmt_p;
#ifdef PRINTF_HAS_LONG_LONG
long long val = value_as_long (value);
#else
long val = value_as_long (value);
#endif
- fmt = (char *) alloca (strlen (format) + 5);
+ /* Build the new output format in FMT. */
+ std::string fmt;
/* Copy up to the leading %. */
- p = format;
- fmt_p = fmt;
+ const char *p = format;
while (*p)
{
int is_percent = (*p == '%');
- *fmt_p++ = *p++;
+ fmt.push_back (*p++);
if (is_percent)
{
if (*p == '%')
- *fmt_p++ = *p++;
+ fmt.push_back (*p++);
else
break;
}
}
if (val != 0)
- *fmt_p++ = '#';
+ fmt.push_back ('#');
/* Copy any width or flags. Only the "-" flag is valid for pointers
-- see the format_pieces constructor. */
while (*p == '-' || (*p >= '0' && *p < '9'))
- *fmt_p++ = *p++;
+ fmt.push_back (*p++);
gdb_assert (*p == 'p' && *(p + 1) == '\0');
if (val != 0)
{
#ifdef PRINTF_HAS_LONG_LONG
- *fmt_p++ = 'l';
+ fmt.push_back ('l');
#endif
- *fmt_p++ = 'l';
- *fmt_p++ = 'x';
- *fmt_p++ = '\0';
+ fmt.push_back ('l');
+ fmt.push_back ('x');
DIAGNOSTIC_PUSH
DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
- gdb_printf (stream, fmt, val);
+ gdb_printf (stream, fmt.c_str (), val);
DIAGNOSTIC_POP
}
else
{
- *fmt_p++ = 's';
- *fmt_p++ = '\0';
+ fmt.push_back ('s');
DIAGNOSTIC_PUSH
DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
- gdb_printf (stream, fmt, "(nil)");
+ gdb_printf (stream, fmt.c_str (), "(nil)");
DIAGNOSTIC_POP
}
}