Print this page
6375 Add native name demangling support
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Richard Lowe <richlowe@richlowe.net>

*** 20,42 **** */ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ - #pragma ident "%Z%%M% %I% %E% SMI" - #include <ctype.h> #include <string.h> #include <sys/param.h> #include <stdlib.h> #include "conv.h" #include "gprof.h" void print_demangled_name(int, nltype *); ! void striped_name(char *, nltype **); extern long hz; /* * Symbols that must never be printed, no matter what. --- 20,43 ---- */ /* * 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> #include <stdlib.h> #include "conv.h" #include "gprof.h" void print_demangled_name(int, nltype *); ! static void stripped_name(char **, size_t *, nltype **); extern long hz; /* * Symbols that must never be printed, no matter what.
*** 498,510 **** { const char *c; c = demangled_name(selfp); if (selfp->name != 0) { - if (!Cflag) - (void) printf("%s", selfp->name); - else (void) printf("%s", c); #ifdef DEBUG if (debug & DFNDEBUG) (void) printf("{%d} ", selfp->toporder); --- 499,508 ----
*** 521,548 **** if (selfp->printflag) (void) printf(" [%d]", selfp->index); else (void) printf(" (%d)", selfp->index); } } void print_demangled_name(int n, nltype *selfp) { ! char *c; int i; ! c = selfp->name; ! ! if (strcmp(c, demangled_name(selfp)) == 0) return; ! else { (void) printf("\n"); for (i = 1; i < n; i++) (void) printf(" "); (void) printf("[%s]", selfp->name); ! } } void sortchildren(nltype *parentp) { --- 519,548 ---- if (selfp->printflag) (void) printf(" [%d]", selfp->index); else (void) printf(" (%d)", selfp->index); } + + if (c != selfp->name) + free((void *)c); } void print_demangled_name(int n, nltype *selfp) { ! char *c = (char *)demangled_name(selfp); int i; ! if (c == selfp->name) return; ! (void) printf("\n"); for (i = 1; i < n; i++) (void) printf(" "); (void) printf("[%s]", selfp->name); ! ! free(c); } void sortchildren(nltype *parentp) {
*** 860,902 **** (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); return (strcmp(s1, s2)); } } ! void ! striped_name(char *s, nltype **npp) { ! const char *d; char *c; ! c = (char *)s; ! d = demangled_name(*npp); while ((*d != '(') && (*d != '\0')) { if (*d != ':') *c++ = *d++; else d++; } *c = '\0'; } /* * Checks if the current symbol name is the same as its neighbour and * returns TRUE if it is. --- 860,933 ---- (void) putchar(input); (void) fclose(blurbfile); } 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 { ! 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)); } } ! #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; ! name = d = demangled_name(*npp); ! adjust_size(sp, slenp, name); ! c = *sp; while ((*d != '(') && (*d != '\0')) { if (*d != ':') *c++ = *d++; else d++; } *c = '\0'; + + if ((*npp)->name != name) + free((void *)name); } /* * Checks if the current symbol name is the same as its neighbour and * returns TRUE if it is.
*** 970,984 **** 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]; --- 1001,1010 ----
*** 1036,1052 **** const char *d = demangled_name(nlp); if (does_clash(namesortnlp, i, nnames)) { (void) printf("%6.6s %d:%s\n", peterbuffer, nlp->module->id, d); ! } else (void) printf("%6.6s %s\n", peterbuffer, d); ! if (d != nlp->name) (void) printf("%6.6s [%s]", "", nlp->name); } else { (void) printf("%6.6s ", peterbuffer); (void) sprintf(peterbuffer, "<cycle %d>", nlp->cycleno); (void) printf("%-33.33s", peterbuffer); --- 1062,1081 ---- const char *d = demangled_name(nlp); if (does_clash(namesortnlp, i, nnames)) { (void) printf("%6.6s %d:%s\n", peterbuffer, nlp->module->id, d); ! } else { (void) printf("%6.6s %s\n", peterbuffer, d); + } ! if (d != nlp->name) { (void) printf("%6.6s [%s]", "", nlp->name); + free((void *)d); + } } else { (void) printf("%6.6s ", peterbuffer); (void) sprintf(peterbuffer, "<cycle %d>", nlp->cycleno); (void) printf("%-33.33s", peterbuffer);