Print this page
10816 ctf_dwarf_convert_type() relies on un-initialized id
10817 ctfconvert -i option is mis-handled
10818 Improve ctfconvert error messages
10819 ctfconvert should handle empty dies
10820 ctfconvert -i never converts
10821 bad free in ctf_dwarf_init_die
10815 shouldn't build gcore.c as part of kmdb
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/ctfconvert/ctfconvert.c
          +++ new/usr/src/cmd/ctfconvert/ctfconvert.c
↓ open down ↓ 2 lines elided ↑ open up ↑
   3    3   * Common Development and Distribution License ("CDDL"), version 1.0.
   4    4   * You may only use this file in accordance with the terms of version
   5    5   * 1.0 of the CDDL.
   6    6   *
   7    7   * A full copy of the text of the CDDL should have accompanied this
   8    8   * source.  A copy of the CDDL is also available via the Internet at
   9    9   * http://www.illumos.org/license/CDDL.
  10   10   */
  11   11  
  12   12  /*
  13      - * Copyright (c) 2015, Joyent, Inc.
       13 + * Copyright (c) 2019, Joyent, Inc.
  14   14   */
  15   15  
  16   16  /*
  17   17   * Create CTF from extant debugging information
  18   18   */
  19   19  
  20   20  #include <stdio.h>
  21   21  #include <unistd.h>
  22   22  #include <stdlib.h>
  23   23  #include <stdarg.h>
↓ open down ↓ 38 lines elided ↑ open up ↑
  62   62  {
  63   63          if (fmt != NULL) {
  64   64                  va_list ap;
  65   65  
  66   66                  (void) fprintf(stderr, "%s: ", ctfconvert_progname);
  67   67                  va_start(ap, fmt);
  68   68                  (void) vfprintf(stderr, fmt, ap);
  69   69                  va_end(ap);
  70   70          }
  71   71  
  72      -        (void) fprintf(stderr, "Usage: %s [-is] [-j nthrs] [-l label | "
       72 +        (void) fprintf(stderr, "Usage: %s [-ims] [-j nthrs] [-l label | "
  73   73              "-L labelenv] [-o outfile] input\n"
  74   74              "\n"
  75   75              "\t-i  ignore files not built partially from C sources\n"
  76   76              "\t-j  use nthrs threads to perform the merge\n"
  77   77              "\t-k  keep around original input file on failure\n"
       78 +            "\t-m  allow input to have missing debug info\n"
  78   79              "\t-o  copy input to outfile and add CTF\n"
  79   80              "\t-l  set output container's label to specified value\n"
  80   81              "\t-L  set output container's label to value from environment\n",
  81   82              ctfconvert_progname);
  82   83  }
  83   84  
  84   85  /*
  85   86   * This is a bit unfortunate. Traditionally we do type uniquification across all
  86   87   * modules in the kernel, including ip and unix against genunix. However, when
  87   88   * _MACHDEP is defined, then the cpu_t ends up having an additional member
↓ open down ↓ 164 lines elided ↑ open up ↑
 252  253          uint_t nthreads = CTFCONVERT_DEFAULT_NTHREADS;
 253  254          const char *outfile = NULL;
 254  255          const char *label = NULL;
 255  256          const char *infile = NULL;
 256  257          char *tmpfile;
 257  258          ctf_file_t *ofp;
 258  259          long argj;
 259  260          char *eptr;
 260  261          char buf[4096];
 261  262          boolean_t optx = B_FALSE;
      263 +        boolean_t ignore_non_c = B_FALSE;
 262  264  
 263  265          ctfconvert_progname = basename(argv[0]);
 264  266  
 265  267          ctfconvert_altexec(argv);
 266  268  
 267      -        while ((c = getopt(argc, argv, ":j:kl:L:o:iX")) != -1) {
      269 +        while ((c = getopt(argc, argv, ":ij:kl:L:mo:X")) != -1) {
 268  270                  switch (c) {
 269      -                case 'k':
 270      -                        keep = B_TRUE;
      271 +                case 'i':
      272 +                        ignore_non_c = B_TRUE;
 271  273                          break;
 272      -                case 'l':
 273      -                        label = optarg;
 274      -                        break;
 275      -                case 'L':
 276      -                        label = getenv(optarg);
 277      -                        break;
 278  274                  case 'j':
 279  275                          errno = 0;
 280  276                          argj = strtol(optarg, &eptr, 10);
 281  277                          if (errno != 0 || argj == LONG_MAX ||
 282  278                              argj > 1024 || *eptr != '\0') {
 283  279                                  ctfconvert_fatal("invalid argument for -j: "
 284  280                                      "%s\n", optarg);
 285  281                          }
 286  282                          nthreads = (uint_t)argj;
 287  283                          break;
      284 +                case 'k':
      285 +                        keep = B_TRUE;
      286 +                        break;
      287 +                case 'l':
      288 +                        label = optarg;
      289 +                        break;
      290 +                case 'L':
      291 +                        label = getenv(optarg);
      292 +                        break;
      293 +                case 'm':
      294 +                        flags |= CTF_ALLOW_MISSING_DEBUG;
      295 +                        break;
 288  296                  case 'o':
 289  297                          outfile = optarg;
 290  298                          break;
 291      -                case 'i':
 292      -                        flags |= CTF_CONVERT_F_IGNNONC;
 293      -                        break;
 294  299                  case 'X':
 295  300                          optx = B_TRUE;
 296  301                          break;
 297  302                  case ':':
 298  303                          ctfconvert_usage("Option -%c requires an operand\n",
 299  304                              optopt);
 300  305                          return (CTFCONVERT_USAGE);
 301  306                  case '?':
 302  307                          ctfconvert_usage("Unknown option: -%c\n", optopt);
 303  308                          return (CTFCONVERT_USAGE);
 304  309                  }
 305  310          }
 306  311  
 307  312          argv += optind;
 308  313          argc -= optind;
 309  314  
 310      -        if (argc < 1) {
 311      -                ctfconvert_usage("Missing required input file\n");
      315 +        if (argc != 1) {
      316 +                ctfconvert_usage("Exactly one input file is required\n");
 312  317                  return (CTFCONVERT_USAGE);
 313  318          }
 314  319          infile = argv[0];
 315  320  
 316  321          if (elf_version(EV_CURRENT) == EV_NONE)
 317  322                  ctfconvert_fatal("failed to initialize libelf: library is "
 318  323                      "out of date\n");
 319  324  
 320  325          ifd = open(infile, O_RDONLY);
 321  326          if (ifd < 0) {
↓ open down ↓ 5 lines elided ↑ open up ↑
 327  332           * By default we remove the input file on failure unless we've been
 328  333           * given an output file or -k has been specified.
 329  334           */
 330  335          if (outfile != NULL && strcmp(infile, outfile) != 0)
 331  336                  keep = B_TRUE;
 332  337  
 333  338          ofp = ctf_fdconvert(ifd, label, nthreads, flags, &err, buf,
 334  339              sizeof (buf));
 335  340          if (ofp == NULL) {
 336  341                  /*
 337      -                 * -i says that we shouldn't concern ourselves with source files
 338      -                 * that weren't built from C source code in part. Because this
 339      -                 * has been traditionally used across all of illumos, we still
 340      -                 * honor it.
      342 +                 * Normally, ctfconvert requires that its input file has at
      343 +                 * least one C-source compilation unit, and that every C-source
      344 +                 * compilation unit has DWARF. This is to avoid accidentally
      345 +                 * leaving out useful CTF.
      346 +                 *
      347 +                 * However, for the benefit of intransigent build environments,
      348 +                 * the -i and -m options can be used to relax this.
 341  349                   */
 342      -                if ((flags & CTF_CONVERT_F_IGNNONC) != 0 &&
 343      -                    err == ECTF_CONVNOCSRC) {
      350 +                if (err == ECTF_CONVNOCSRC && ignore_non_c) {
 344  351                          exit(CTFCONVERT_OK);
 345  352                  }
      353 +
      354 +                if (err == ECTF_CONVNODEBUG &&
      355 +                    (flags & CTF_ALLOW_MISSING_DEBUG) != 0) {
      356 +                        exit(CTFCONVERT_OK);
      357 +                }
      358 +
 346  359                  if (keep == B_FALSE)
 347  360                          (void) unlink(infile);
 348      -                ctfconvert_fatal("CTF conversion failed: %s\n",
 349      -                    err == ECTF_CONVBKERR ? buf : ctf_errmsg(err));
      361 +
      362 +                if (err == ECTF_CONVBKERR || err == ECTF_CONVNODEBUG) {
      363 +                        ctfconvert_fatal("%s", buf);
      364 +                } else {
      365 +                        ctfconvert_fatal("CTF conversion failed: %s\n",
      366 +                            ctf_errmsg(err));
      367 +                }
 350  368          }
 351  369  
 352  370          if (optx == B_TRUE)
 353  371                  ctfconvert_fixup_genunix(ofp);
 354  372  
 355  373          tmpfile = NULL;
 356  374          if (outfile == NULL || strcmp(infile, outfile) == 0) {
 357  375                  if (asprintf(&tmpfile, "%s.ctf", infile) == -1) {
 358  376                          if (keep == B_FALSE)
 359  377                                  (void) unlink(infile);
↓ open down ↓ 29 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX