| Summary: | Strange differences in D runtime debug-info between builds | ||
|---|---|---|---|
| Product: | gcc | Reporter: | Richard Biener <rguenth> |
| Component: | d | Assignee: | Richard Biener <rguenth> |
| Status: | RESOLVED FIXED | ||
| Severity: | normal | ||
| Priority: | P3 | ||
| Version: | 9.0 | ||
| Target Milestone: | --- | ||
| Host: | Target: | ||
| Build: | Known to work: | 9.1.1 | |
| Known to fail: | Last reconfirmed: | 2019-06-07 00:00:00 | |
| Attachments: | untested patch | ||
Created attachment 46460 [details]
untested patch
This might fix it.
Patch posted. Fixed. (looks like commits with d/N do not get bugzilla mails) |
We see builds of the D runtime be not reproducible when compiling from the same source multiple times. This for example shows in libdruntime/rt/lifetime.d objects which have @@ -3853,17 +3853,17 @@ <2212> DW_AT_location : 0x1692 (location list) <2216> DW_AT_GNU_locviews: 0x1684 <2><221a>: Abbrev Number: 48 (DW_TAG_label) - <221b> DW_AT_name : (indirect string, offset: 0x22f2): Lcontinue + <221b> DW_AT_name : (indirect string, offset: 0xcac): Loverflow <221f> DW_AT_decl_file : 1 - <2220> DW_AT_decl_line : 784 + <2220> DW_AT_decl_line : 781 <2222> DW_AT_decl_column : 1 - <2223> DW_AT_low_pc : 0xaaa + <2223> DW_AT_low_pc : 0xe4e <2><222b>: Abbrev Number: 48 (DW_TAG_label) - <222c> DW_AT_name : (indirect string, offset: 0xcdc): Loverflow + <222c> DW_AT_name : (indirect string, offset: 0x22f2): Lcontinue <2230> DW_AT_decl_file : 1 - <2231> DW_AT_decl_line : 781 + <2231> DW_AT_decl_line : 784 <2233> DW_AT_decl_column : 1 - <2234> DW_AT_low_pc : 0xe4e + <2234> DW_AT_low_pc : 0xaaa <2><223c>: Abbrev Number: 9 (DW_TAG_variable) <223d> DW_AT_name : tgt <2241> DW_AT_decl_file : 1 which appears in <1><21b2>: Abbrev Number: 21 (DW_TAG_subprogram) <21b3> DW_AT_external : 1 <21b3> DW_AT_name : (indirect string, offset: 0x880): _d_arraysetcapacity <21b7> DW_AT_decl_file : 1 <21b8> DW_AT_decl_line : 734 <21ba> DW_AT_decl_column : 18 <21bb> DW_AT_type : <0x29> <21bf> DW_AT_low_pc : 0xa00 <21c7> DW_AT_high_pc : 0x46b <21cf> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <21d1> DW_AT_GNU_all_call_sites: 1 <21d1> DW_AT_sibling : <0x2609> it looks like D maintains labels in a hash-map, doing /* Pop all the labels declared in the function. */ if (d_function_chain->labels) d_function_chain->labels->traverse<tree, &pop_label> (block); and bool pop_label (Statement * const &s, d_label_entry *ent, tree block) { if (!ent->bc_label) { /* Put the labels into the "variables" of the top-level block, so debugger can see them. */ if (DECL_NAME (ent->label)) { gcc_assert (DECL_INITIAL (ent->label) != NULL_TREE); DECL_CHAIN (ent->label) = BLOCK_VARS (block); BLOCK_VARS (block) = ent->label; so the order of labels depend on the order of them appearing in the hashtable which means depending on virtual addresses and hashtable size. I suggest to fix this by sorting the labels after DECL_UID (which should order them after time of creation which should roughly match parsing/source order) and emit them from there. This means putting the hashtable contents into a vector and sorting that, sth GCC does elsewhere to avoid random code-generation differences with for example address-space randomization. grepping for 'traverse' this might be the only place D does this. I'm also not sure it is safe to remove elements while traversing.