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

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/sgs/gprof/common/printgprof.c
          +++ new/usr/src/cmd/sgs/gprof/common/printgprof.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
       25 + *
       26 + * Copyright 2018 Jason King
       27 + * Copyright 2018, Joyent, Inc.
  25   28   */
  26   29  
  27      -#pragma ident   "%Z%%M% %I%     %E% SMI"
  28      -
  29   30  #include <ctype.h>
  30   31  #include <string.h>
  31   32  #include <sys/param.h>
  32   33  #include <stdlib.h>
  33   34  #include "conv.h"
  34   35  #include "gprof.h"
  35   36  
  36   37  void print_demangled_name(int, nltype *);
  37      -void striped_name(char *, nltype **);
       38 +static void stripped_name(char **, size_t *, nltype **);
  38   39  
  39   40  extern long hz;
  40   41  
  41   42  /*
  42   43   * Symbols that must never be printed, no matter what.
  43   44   */
  44   45  char *splsym[] = {
  45   46          PRF_ETEXT,
  46   47          PRF_EXTSYM,
  47   48          PRF_MEMTERM,
↓ open down ↓ 10 lines elided ↑ open up ↑
  58   59  
  59   60          return (conv_demangle_name(selfp->name));
  60   61  }
  61   62  
  62   63  void
  63   64  printprof(void)
  64   65  {
  65   66          nltype  *np;
  66   67          nltype  **sortednlp;
  67   68          int     i, index;
  68      -        int     print_count = number_funcs_toprint;
       69 +        int     print_count = number_funcs_toprint;
  69   70          bool    print_flag = TRUE;
  70   71          mod_info_t      *mi;
  71   72  
  72   73          actime = 0.0;
  73   74          (void) printf("\f\n");
  74   75          flatprofheader();
  75   76  
  76   77          /*
  77   78           *      Sort the symbol table in by time
  78   79           */
↓ open down ↓ 207 lines elided ↑ open up ↑
 286  287                          return (TRUE);
 287  288  
 288  289          return (FALSE);
 289  290  }
 290  291  
 291  292  void
 292  293  printgprof(nltype **timesortnlp)
 293  294  {
 294  295          int     index;
 295  296          nltype  *parentp;
 296      -        int     print_count = number_funcs_toprint;
      297 +        int     print_count = number_funcs_toprint;
 297  298          bool    count_flag = TRUE;
 298  299  
 299  300          /*
 300  301           * Print out the structured profiling list
 301  302           */
 302  303          gprofheader();
 303  304  
 304  305          for (index = 0; index < total_names + ncycle && count_flag; index++) {
 305  306                  parentp = timesortnlp[index];
 306  307                  if (zflag == 0 && parentp->ncall == 0 &&
↓ open down ↓ 186 lines elided ↑ open up ↑
 493  494          }
 494  495  }
 495  496  
 496  497  void
 497  498  printname(nltype *selfp)
 498  499  {
 499  500          const char  *c;
 500  501          c = demangled_name(selfp);
 501  502  
 502  503          if (selfp->name != 0) {
 503      -                if (!Cflag)
 504      -                        (void) printf("%s", selfp->name);
 505      -                else
 506      -                        (void) printf("%s", c);
      504 +                (void) printf("%s", c);
 507  505  
 508  506  #ifdef DEBUG
 509  507                  if (debug & DFNDEBUG)
 510  508                          (void) printf("{%d} ", selfp->toporder);
 511  509  
 512  510                  if (debug & PROPDEBUG)
 513  511                          (void) printf("%5.2f%% ", selfp->propfraction);
 514  512  #endif /* DEBUG */
 515  513          }
 516  514  
 517  515          if (selfp->cycleno != 0)
 518  516                  (void) printf("\t<cycle %d>", selfp->cycleno);
 519  517  
 520  518          if (selfp->index != 0) {
 521  519                  if (selfp->printflag)
 522  520                          (void) printf(" [%d]", selfp->index);
 523  521                  else
 524  522                          (void) printf(" (%d)", selfp->index);
 525  523          }
      524 +
      525 +        if (c != selfp->name)
      526 +                free((void *)c);
 526  527  }
 527  528  
 528  529  void
 529  530  print_demangled_name(int n, nltype *selfp)
 530  531  {
 531      -        char *c;
      532 +        char *c = (char *)demangled_name(selfp);
 532  533          int i;
 533  534  
 534      -        c = selfp->name;
 535      -
 536      -        if (strcmp(c, demangled_name(selfp)) == 0)
      535 +        if (c == selfp->name)
 537  536                  return;
 538      -        else {
 539      -                (void) printf("\n");
 540      -                for (i = 1; i < n; i++)
 541      -                        (void) printf(" ");
 542      -                (void) printf("[%s]", selfp->name);
 543      -        }
      537 +
      538 +        (void) printf("\n");
      539 +        for (i = 1; i < n; i++)
      540 +                (void) printf(" ");
      541 +        (void) printf("[%s]", selfp->name);
      542 +
      543 +        free(c);
 544  544  }
 545  545  
 546  546  void
 547  547  sortchildren(nltype *parentp)
 548  548  {
 549  549          arctype *arcp;
 550  550          arctype *detachedp;
 551  551          arctype sorted;
 552  552          arctype *prevp;
 553  553  
↓ open down ↓ 301 lines elided ↑ open up ↑
 855  855                  perror(blurbname);
 856  856                  return;
 857  857          }
 858  858  
 859  859          while ((input = getc(blurbfile)) != EOF)
 860  860                  (void) putchar(input);
 861  861  
 862  862          (void) fclose(blurbfile);
 863  863  }
 864  864  
 865      -char *s1, *s2;
 866      -
 867  865  static int
 868  866  namecmp(const void *arg1, const void *arg2)
 869  867  {
 870  868          nltype **npp1 = (nltype **)arg1;
 871  869          nltype **npp2 = (nltype **)arg2;
 872  870  
 873  871          if (!Cflag)
 874  872                  return (strcmp((*npp1)->name, (*npp2)->name));
 875  873          else {
 876      -                striped_name(s1, npp1);
 877      -                striped_name(s2, npp2);
      874 +                static char *s1 = NULL, *s2 = NULL;
      875 +                static size_t s1len = 0, s2len = 0;
      876 +
      877 +                stripped_name(&s1, &s1len, npp1);
      878 +                stripped_name(&s2, &s2len, npp2);
 878  879                  return (strcmp(s1, s2));
 879  880          }
 880  881  }
 881  882  
 882      -void
 883      -striped_name(char *s, nltype **npp)
      883 +#define NAME_CHUNK 512
      884 +#define ROUNDLEN(x) (((x) + NAME_CHUNK - 1) / NAME_CHUNK * NAME_CHUNK)
      885 +static void
      886 +adjust_size(char **pp, size_t *lenp, const char *name)
 884  887  {
 885      -        const char *d;
      888 +        void *newp;
      889 +        size_t nlen = strlen(name);
      890 +        size_t buflen;
      891 +
      892 +        if (*lenp > nlen) {
      893 +                (void) memset(*pp, '\0', *lenp);
      894 +                return;
      895 +        }
      896 +
      897 +        buflen = ROUNDLEN(nlen + 1);
      898 +        if ((newp = realloc(*pp, buflen)) == NULL) {
      899 +                (void) fprintf(stderr,
      900 +                    "gprof: out of memory comparing names\n");
      901 +                exit(EXIT_FAILURE);
      902 +        }
      903 +        (void) memset(newp, '\0', buflen);
      904 +
      905 +        *lenp = buflen;
      906 +        *pp = newp;
      907 +}
      908 +
      909 +static void
      910 +stripped_name(char **sp, size_t *slenp, nltype **npp)
      911 +{
      912 +        const char *name, *d;
 886  913          char *c;
 887  914  
 888      -        c = (char *)s;
 889      -        d = demangled_name(*npp);
      915 +        name = d = demangled_name(*npp);
      916 +        adjust_size(sp, slenp, name);
      917 +        c = *sp;
 890  918  
 891  919          while ((*d != '(') && (*d != '\0')) {
 892  920                  if (*d != ':')
 893  921                          *c++ = *d++;
 894  922                  else
 895  923                          d++;
 896  924          }
 897  925          *c = '\0';
      926 +
      927 +        if ((*npp)->name != name)
      928 +                free((void *)name);
 898  929  }
 899  930  
 900  931  /*
 901  932   * Checks if the current symbol name is the same as its neighbour and
 902  933   * returns TRUE if it is.
 903  934   */
 904  935  static bool
 905  936  does_clash(nltype **nlp, int ndx, int nnames)
 906  937  {
 907  938          /*
↓ open down ↓ 57 lines elided ↑ open up ↑
 965  996                           * Do not print certain special symbols, like
 966  997                           * PRF_EXTSYM, etc. even if zflag was on.
 967  998                           */
 968  999                          if (is_special_sym(&(mi->nl[index])))
 969 1000                                  continue;
 970 1001  
 971 1002                          namesortnlp[nnames++] = &(mi->nl[index]);
 972 1003                  }
 973 1004          }
 974 1005  
 975      -        if (Cflag) {
 976      -                s1 = malloc(500 * sizeof (char));
 977      -                s2 = malloc(500 * sizeof (char));
 978      -        }
 979      -
 980 1006          qsort(namesortnlp, nnames, sizeof (nltype *), namecmp);
 981 1007  
 982 1008          for (index = 1, todo = nnames; index <= ncycle; index++)
 983 1009                  namesortnlp[todo++] = &cyclenl[index];
 984 1010  
 985 1011          (void) printf("\f\nIndex by function name\n\n");
 986 1012  
 987 1013          if (!Cflag)
 988 1014                  index = (todo + 2) / 3;
 989 1015          else
↓ open down ↓ 41 lines elided ↑ open up ↑
1031 1057                                  (void) sprintf(peterbuffer, "[%d]", nlp->index);
1032 1058                          else
1033 1059                                  (void) sprintf(peterbuffer, "(%d)", nlp->index);
1034 1060  
1035 1061                          if (i < nnames) {
1036 1062                                  const char *d = demangled_name(nlp);
1037 1063  
1038 1064                                  if (does_clash(namesortnlp, i, nnames)) {
1039 1065                                          (void) printf("%6.6s %d:%s\n",
1040 1066                                              peterbuffer, nlp->module->id, d);
1041      -                                } else
     1067 +                                } else {
1042 1068                                          (void) printf("%6.6s %s\n", peterbuffer,
1043 1069                                              d);
     1070 +                                }
1044 1071  
1045      -                                if (d != nlp->name)
     1072 +                                if (d != nlp->name) {
1046 1073                                          (void) printf("%6.6s   [%s]", "",
1047 1074                                              nlp->name);
     1075 +                                        free((void *)d);
     1076 +                                }
1048 1077                          } else {
1049 1078                                  (void) printf("%6.6s ", peterbuffer);
1050 1079                                  (void) sprintf(peterbuffer, "<cycle %d>",
1051 1080                                      nlp->cycleno);
1052 1081                                  (void) printf("%-33.33s", peterbuffer);
1053 1082                          }
1054 1083                  }
1055 1084                  (void) printf("\n");
1056 1085          }
1057 1086          free(namesortnlp);
1058 1087  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX