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>

@@ -8,11 +8,11 @@
  * source.  A copy of the CDDL is also available via the Internet at
  * http://www.illumos.org/license/CDDL.
  */
 
 /*
- * Copyright (c) 2015, Joyent, Inc.
+ * Copyright (c) 2019, Joyent, Inc.
  */
 
 /*
  * Create CTF from extant debugging information
  */

@@ -67,16 +67,17 @@
                 va_start(ap, fmt);
                 (void) vfprintf(stderr, fmt, ap);
                 va_end(ap);
         }
 
-        (void) fprintf(stderr, "Usage: %s [-is] [-j nthrs] [-l label | "
+        (void) fprintf(stderr, "Usage: %s [-ims] [-j nthrs] [-l label | "
             "-L labelenv] [-o outfile] input\n"
             "\n"
             "\t-i  ignore files not built partially from C sources\n"
             "\t-j  use nthrs threads to perform the merge\n"
             "\t-k  keep around original input file on failure\n"
+            "\t-m  allow input to have missing debug info\n"
             "\t-o  copy input to outfile and add CTF\n"
             "\t-l  set output container's label to specified value\n"
             "\t-L  set output container's label to value from environment\n",
             ctfconvert_progname);
 }

@@ -257,26 +258,21 @@
         ctf_file_t *ofp;
         long argj;
         char *eptr;
         char buf[4096];
         boolean_t optx = B_FALSE;
+        boolean_t ignore_non_c = B_FALSE;
 
         ctfconvert_progname = basename(argv[0]);
 
         ctfconvert_altexec(argv);
 
-        while ((c = getopt(argc, argv, ":j:kl:L:o:iX")) != -1) {
+        while ((c = getopt(argc, argv, ":ij:kl:L:mo:X")) != -1) {
                 switch (c) {
-                case 'k':
-                        keep = B_TRUE;
+                case 'i':
+                        ignore_non_c = B_TRUE;
                         break;
-                case 'l':
-                        label = optarg;
-                        break;
-                case 'L':
-                        label = getenv(optarg);
-                        break;
                 case 'j':
                         errno = 0;
                         argj = strtol(optarg, &eptr, 10);
                         if (errno != 0 || argj == LONG_MAX ||
                             argj > 1024 || *eptr != '\0') {

@@ -283,16 +279,25 @@
                                 ctfconvert_fatal("invalid argument for -j: "
                                     "%s\n", optarg);
                         }
                         nthreads = (uint_t)argj;
                         break;
+                case 'k':
+                        keep = B_TRUE;
+                        break;
+                case 'l':
+                        label = optarg;
+                        break;
+                case 'L':
+                        label = getenv(optarg);
+                        break;
+                case 'm':
+                        flags |= CTF_ALLOW_MISSING_DEBUG;
+                        break;
                 case 'o':
                         outfile = optarg;
                         break;
-                case 'i':
-                        flags |= CTF_CONVERT_F_IGNNONC;
-                        break;
                 case 'X':
                         optx = B_TRUE;
                         break;
                 case ':':
                         ctfconvert_usage("Option -%c requires an operand\n",

@@ -305,12 +310,12 @@
         }
 
         argv += optind;
         argc -= optind;
 
-        if (argc < 1) {
-                ctfconvert_usage("Missing required input file\n");
+        if (argc != 1) {
+                ctfconvert_usage("Exactly one input file is required\n");
                 return (CTFCONVERT_USAGE);
         }
         infile = argv[0];
 
         if (elf_version(EV_CURRENT) == EV_NONE)

@@ -332,24 +337,37 @@
 
         ofp = ctf_fdconvert(ifd, label, nthreads, flags, &err, buf,
             sizeof (buf));
         if (ofp == NULL) {
                 /*
-                 * -i says that we shouldn't concern ourselves with source files
-                 * that weren't built from C source code in part. Because this
-                 * has been traditionally used across all of illumos, we still
-                 * honor it.
+                 * Normally, ctfconvert requires that its input file has at
+                 * least one C-source compilation unit, and that every C-source
+                 * compilation unit has DWARF. This is to avoid accidentally
+                 * leaving out useful CTF.
+                 *
+                 * However, for the benefit of intransigent build environments,
+                 * the -i and -m options can be used to relax this.
                  */
-                if ((flags & CTF_CONVERT_F_IGNNONC) != 0 &&
-                    err == ECTF_CONVNOCSRC) {
+                if (err == ECTF_CONVNOCSRC && ignore_non_c) {
                         exit(CTFCONVERT_OK);
                 }
+
+                if (err == ECTF_CONVNODEBUG &&
+                    (flags & CTF_ALLOW_MISSING_DEBUG) != 0) {
+                        exit(CTFCONVERT_OK);
+                }
+
                 if (keep == B_FALSE)
                         (void) unlink(infile);
+
+                if (err == ECTF_CONVBKERR || err == ECTF_CONVNODEBUG) {
+                        ctfconvert_fatal("%s", buf);
+                } else {
                 ctfconvert_fatal("CTF conversion failed: %s\n",
-                    err == ECTF_CONVBKERR ? buf : ctf_errmsg(err));
+                            ctf_errmsg(err));
         }
+        }
 
         if (optx == B_TRUE)
                 ctfconvert_fixup_genunix(ofp);
 
         tmpfile = NULL;