Project

General

Profile

Actions

Bug #10922

closed

libctf apparently erroneously assumes upper-bound of array size is non-negative

Added by Rich Lowe over 4 years ago. Updated over 4 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Category:
tools - gate/build tools
Start date:
2019-05-06
Due date:
% Done:

0%

Estimated time:
Difficulty:
Medium
Tags:
needs-triage
Gerrit CR:
External Bug:

Description

I sound crazy, I know. I feel it as well.

Igor merged some ZFS changes, that include the definition of this variable:

static const zfs_ioc_key_t zfs_keys_remap[] = {
    /* no nvl keys */
};

For which his compiler generated the following DWARF:

< 1><0x0001b93e>    DW_TAG_array_type
                      DW_AT_type                  <0x0001b7bd>
                      DW_AT_sibling               <0x0001b94e>
< 2><0x0001b947>      DW_TAG_subrange_type
                        DW_AT_type                  <0x0001b953>
                        DW_AT_upper_bound           0xffffffffffffffff (-1)
< 1><0x0001b94e>    DW_TAG_const_type
                      DW_AT_type                  <0x0001b93e>
< 1><0x0001b95a>    DW_TAG_variable
                      DW_AT_name                  zfs_keys_remap
                      DW_AT_decl_file             0x00000001 /rws1/users/igor/dilos-illumos.zfs/usr/src/uts/intel/zfs/../../common/fs/zfs/zfs_ioctl.c
                      DW_AT_decl_line             0x00000d84
                      DW_AT_type                  <0x0001b94e>
                      DW_AT_location              DW_OP_addr 0x000004b0

which for reasons I don't understand, has an upper bound of -1. We assume that we can get DW_AT_upper_bound as unsigned, and thus fail.

A simple test case is:

struct yuck {
    int a;
    int b;
};

const struct yuck yucks[] = {
    /* no yucks to give */
};


Related issues

Is duplicate of illumos gate - Bug #10854: empty struct array confuses CTFClosed2019-04-25

Actions
Actions #1

Updated by Rich Lowe over 4 years ago

It seems libctf tries to handle this, but only skips the failure if ctf_get_unsigned() returns ENOENT, which it will not, it'll return ECTF_CONVBKERR

The obvious hack

@@ -1426,7 +1436,7 @@ ctf_dwarf_create_array_range(ctf_cu_t *cup, Dwarf_Die range, ctf_id_t *idp,
        if ((ret = ctf_dwarf_unsigned(cup, range, DW_AT_upper_bound,
            &val)) == 0) {
                ar.ctr_nelems = val + 1;
-       } else if (ret != ENOENT) {
+       } else if ((ret != ENOENT) && (ret != ECTF_CONVBKERR)) {
                return (ret);
        } else if ((ret = ctf_dwarf_signed(cup, range, DW_AT_upper_bound,
            &sval)) == 0) {

Appears to work, though it's unclear whether it's correct, because I'm not 100% clear what the condition was trying to do, and why it talked of this case but didn't account for it. Perhaps I'm misreading the comment?

Actions #2

Updated by John Levon over 4 years ago

  • Status changed from New to Closed

Dupe of #10854

Actions #3

Updated by Gergő Mihály Doma over 4 years ago

  • Is duplicate of Bug #10854: empty struct array confuses CTF added
Actions

Also available in: Atom PDF