Print this page
gprof shouldn't assume names are less than 500 bytes
@@ -22,10 +22,11 @@
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Copyright 2018 Jason King
+ * Copyright 2018, Joyent, Inc.
*/
#include <ctype.h>
#include <string.h>
#include <sys/param.h>
@@ -32,11 +33,11 @@
#include <stdlib.h>
#include "conv.h"
#include "gprof.h"
void print_demangled_name(int, nltype *);
-void striped_name(char *, nltype **);
+static void stripped_name(char **, size_t *, nltype **);
extern long hz;
/*
* Symbols that must never be printed, no matter what.
@@ -859,35 +860,63 @@
(void) putchar(input);
(void) fclose(blurbfile);
}
-char *s1, *s2;
-
static int
namecmp(const void *arg1, const void *arg2)
{
nltype **npp1 = (nltype **)arg1;
nltype **npp2 = (nltype **)arg2;
if (!Cflag)
return (strcmp((*npp1)->name, (*npp2)->name));
else {
- striped_name(s1, npp1);
- striped_name(s2, npp2);
+ static char *s1 = NULL, *s2 = NULL;
+ static size_t s1len = 0, s2len = 0;
+
+ stripped_name(&s1, &s1len, npp1);
+ stripped_name(&s2, &s2len, npp2);
return (strcmp(s1, s2));
}
}
-void
-striped_name(char *s, nltype **npp)
+#define NAME_CHUNK 512
+#define ROUNDLEN(x) (((x) + NAME_CHUNK - 1) / NAME_CHUNK * NAME_CHUNK)
+static void
+adjust_size(char **pp, size_t *lenp, const char *name)
{
+ void *newp;
+ size_t nlen = strlen(name);
+ size_t buflen;
+
+ if (*lenp > nlen) {
+ (void) memset(*pp, '\0', *lenp);
+ return;
+ }
+
+ buflen = ROUNDLEN(nlen + 1);
+ if ((newp = realloc(*pp, buflen)) == NULL) {
+ (void) fprintf(stderr,
+ "gprof: out of memory comparing names\n");
+ exit(EXIT_FAILURE);
+ }
+ (void) memset(newp, '\0', buflen);
+
+ *lenp = buflen;
+ *pp = newp;
+}
+
+static void
+stripped_name(char **sp, size_t *slenp, nltype **npp)
+{
const char *name, *d;
char *c;
- c = (char *)s;
name = d = demangled_name(*npp);
+ adjust_size(sp, slenp, name);
+ c = *sp;
while ((*d != '(') && (*d != '\0')) {
if (*d != ':')
*c++ = *d++;
else
@@ -972,15 +1001,10 @@
namesortnlp[nnames++] = &(mi->nl[index]);
}
}
- if (Cflag) {
- s1 = malloc(500 * sizeof (char));
- s2 = malloc(500 * sizeof (char));
- }
-
qsort(namesortnlp, nnames, sizeof (nltype *), namecmp);
for (index = 1, todo = nnames; index <= ncycle; index++)
namesortnlp[todo++] = &cyclenl[index];