Bug 106718 - GCC does not follow DWARF5 standard for DW_AT_ranges and DW_FORM_rnglistx
Summary: GCC does not follow DWARF5 standard for DW_AT_ranges and DW_FORM_rnglistx
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: debug (show other bugs)
Version: 13.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-debug
Depends on:
Blocks:
 
Reported: 2022-08-23 06:17 UTC by Navid Rahimi
Modified: 2022-08-24 17:44 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Navid Rahimi 2022-08-23 06:17:26 UTC
gcc-trunk sort.c -O3 -gdwarf-5 -gsplit-dwarf -g3 -o sort

.
.
.
36> DW_TAG_inlined_subroutine
        DW_AT_abstract_origin   DW_FORM_ref4
        DW_AT_entry_pc  DW_FORM_addrx
                DW_FORM_data1
        DW_AT_ranges    DW_FORM_rnglistx
.
.
.

DWARF5 standard explicitly mentions that you should not use "DW_FORM_rnglistx" form when your header does have offset_entry_count=0.  

"If the offset_entry_count is zero, then DW_FORM_rnglistx cannot be used to access a range list; DW_FORM_sec_offset must be used instead. If the offset_entry_count is non-zero, then DW_FORM_rnglistx may be used to access a range list; this is necessary in split units and may be more compact than using DW_FORM_sec_offsetin non-split units. (Page 242, DWARF5 Specification document)."


I didn't try to bisect to find exact commit, but I didn't have this problem 1 year ago. 


#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#define ARRAY_LEN 50000

static struct timeval tm1;

static inline void start() {
    gettimeofday(&tm1, NULL);
}

static inline void stop() {
    struct timeval tm2;
    gettimeofday(&tm2, NULL);
    unsigned long long t = 1000 * (tm2.tv_sec - tm1.tv_sec) +\
                           (tm2.tv_usec - tm1.tv_usec) / 1000;
    printf("%llu ms\n", t);
}

void bubble_sort (int *a, int n) {
    int i, t, s = 1;
    while (s) {
        s = 0;
        for (i = 1; i < n; i++) {
            if (a[i] < a[i - 1]) {
                t = a[i];
                a[i] = a[i - 1];
                a[i - 1] = t;
                s = 1;
            }
        }
    }
}

void sort_array() {
    printf("Bubble sorting array of %d elements\n", ARRAY_LEN);
    int data[ARRAY_LEN], i;
    for(i=0; i<ARRAY_LEN; ++i){
        data[i] = rand();
    }
    bubble_sort(data, ARRAY_LEN);
}

int main(){
    start();
    sort_array();
    stop();
    return 0;
}
Comment 1 Jakub Jelinek 2022-08-23 13:36:36 UTC
I don't see anything wrong.
DW_AT_ranges in DW_TAG_skeleton_unit in .debug_info section uses DW_FORM_sec_offset and refers to .debug_rnglists section which has
        .long   0       # Offset Entry Count
Then DW_AT_ranges in DW_TAG_inlined_subroutine (twice) and in DW_TAG_lexical_block all in .debug_info.dwo section use DW_FORM_rnglistx, but
those don't refer to .debug_rnglists section, but to .debug_rnglists.dwo
section, which has:
        .long   0x2     # Offset Entry Count
.Ldebug_ranges1:
        .long   .LLRL5-.Ldebug_ranges1
        .long   .LLRL9-.Ldebug_ranges1
Just look at DWARF5 Appendix B. Debug Section Relationships (Informative) graph,
it is the (io) link in there.
Comment 2 Navid Rahimi 2022-08-24 17:43:52 UTC
Thanks for clarifying it. I was able to fix a bug somewhere else with your explanation.
Comment 3 Navid Rahimi 2022-08-24 17:44:54 UTC
Status change to Invalid report.