Closed jeremy-rifkin closed 4 months ago
Please redo the output with
dwarfdump -i -M -G -vv --tied-file=<skelname> dwoname
(focusing on the two TAGs above as you show above). Lets see what dwarfdump says about those two DIEs.
Thanks Dave, I got 522 errors along the lines of NO ENTRY: DW_FORM_addrx is a DW_DLV_NO_ENTRY? something is wrong.:
.
< 1><0x00022223 GOFF=0x00022223> DW_TAG_subprogram <abbrev 25 ABGOFF = 0x00000175 count = 0x00000006>
DW_AT_specification <0x0001a3be GOFF=0x0001a3be> <form DW_FORM_ref4 19>
dwarfdump NO ENTRY: DW_FORM_addrx is a DW_DLV_NO_ENTRY? something is wrong.:
CU Name = (indexed string: 0x000001bc)/path/to/src/cpptrace.cpp
CU Producer = (indexed string: 0x00000f1a)GNU C++17 13.2.0 -mtune=generic -march=x86-64 -gsplit-dwarf -gdwarf-5 -g -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -fasynchronous-unwind-tables -fstack-protector-strong -fstack-clash-protection -fcf-protection
DIE OFF = 0x00022223 GOFF = 0x00022223, Low PC = unknown , High PC = unknown
DW_AT_low_pc
DW_AT_high_pc <offset-from-lowpc> 565 <form DW_FORM_data8 7>
DW_AT_frame_base len 0x0001: 0x9c: <form DW_FORM_exprloc 24>
DW_OP_call_frame_cfa
DW_AT_call_all_tail_calls yes(1) <form DW_FORM_flag_present 25>
DW_AT_sibling <0x000222b4 GOFF=0x000222b4> <form DW_FORM_ref4 19>
Here is the .so and .dwo file in case it may be of help cpptrace-so-and-dwo.zip
There was a recent bug in gcc that gdb folks are working around related to this, but I cannot find it just now.
Problem is in (print_die.c line 9098)
dwarfdump calls
dwarf_formaddr() (print_die.c line 9098)
_dwarf_look_in_local_and_tied()
_dwarf_get_addr_index_itself()
_dwarf_look_in_local_and_tied_by_index
So var I have not been able to figure out where DW_DLV_NO_ENTRY might be returned from libdwarf. in this sequence of calls.
Given you have the objects, try setting a breakpoint on _dwarf_look_in_local_and_tied() and step-over and check the result for DW_DLV_ERROR (1). In case of DW_DLV_NO_ENTRY there is no specific function to put a breakpoint on for that.
Is this dWARF4 or 5?
Ah. _dwarf_get_addr_from_tied() in dwarf_query.c: if (!context->cc_addr_base_present) { / Does not exist. / return DW_DLV_NO_ENTRY; } might not be correct for DWARF4. Hmm.
But if not present the next call, _dwarf_search_for_signature() would work? or Not? and the latter too could return dW_DLV_NO_ENTRY.
Hmm Lots of related data needed and I would have to see what gcc did in Dwarf, both the object (dwo?) and the tied skeleton.
So. Find the first failure.
From the dwarfdump output ( -i -M -G -vv) of the dwo show the CU-die of the failure. And for the skeleton CU that belongs to the dwo CU.
And the DIE (TAG Attrs) for the failure (dwo) and in the skeleton.
So four DIEswith attributes and FORMs from dwarfdump. Children DIEs of these are of no interest.
That will help me. It is possibly all I need to know. I see where the DW_DLV_NO_ENTRY is coming from. Your data will tell me what gcc is doing so I can fix libdwarf.
Thanks Dave, this one is dwarf 5.
I have built dwarfdump locally at commit a54dbb55b436978efc87f854560d2d2253d79e42. Debugging locally:
_dwarf_look_in_local_and_tied
and found _dwarf_look_in_local_and_tied_by_index
is returning DW_DLV_NO_ENTRY
._dwarf_extract_address_from_debug_addr
is returning an error and dwarf_errno is DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION
_dwarf_get_addr_from_tied
is called, returning DW_DLV_NO_ENTRY
DW_DLV_NO_ENTRY
does indeed originate from
if (!context->cc_addr_base_present) {
/* Does not exist. */
return DW_DLV_NO_ENTRY;
}
The CU-die of the failure (in the dwo):
Section Groups data
Number of Elf-like sections: 10
Number of groups : 1
Group to print : 2
Count of map entries : 6
[index] group section
[ 0] 2 1 .debug_info.dwo
[ 1] 2 2 .debug_abbrev.dwo
[ 2] 2 3 .debug_rnglists.dwo
[ 3] 2 4 .debug_line.dwo
[ 4] 2 5 .debug_str_offsets.dwo
[ 5] 2 6 .debug_str.dwo
.debug_info.dwo
CU_HEADER:
cu_header_length = 0x00023bd9 146393
version_stamp = 0x0005 5
abbrev_offset = 0x00000000 0
address_size = 0x08 8
offset_size = 0x04 4
cu_type = 0x05 DW_UT_split_compile
signature = 0x10ec1965cadc101e
typeoffset = 0x00000000 0
COMPILE_UNIT<header overall offset = 0x00000000>:
< 0><0x00000014 GOFF=0x00000014> DW_TAG_compile_unit <abbrev 208 ABGOFF = 0x00000f5d count = 0x00000004>
DW_AT_producer (indexed string: 0x00000f1a)GNU C++17 13.2.0 -mtune=generic -march=x86-64 -gsplit-dwarf -gdwarf-5 -g -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -fasynchronous-unwind-tables -fstack-protector-strong -fstack-clash-protection -fcf-protection <form DW_FORM_strx 26>
DW_AT_language DW_LANG_C_plus_plus_14 <form DW_FORM_data1 11>
DW_AT_name (indexed string: 0x000001bc)/mnt/c/Users/rifkin/home/projects/cpptrace/src/cpptrace.cpp <form DW_FORM_strx 26>
DW_AT_comp_dir (indexed string: 0x00000771)/mnt/c/Users/rifkin/home/projects/cpptrace/build <form DW_FORM_strx 26>
The skeleton CU:
CU_HEADER:
cu_header_length = 0x0000002d 45
version_stamp = 0x0005 5
abbrev_offset = 0x0000007e 126
address_size = 0x08 8
offset_size = 0x04 4
cu_type = 0x04 DW_UT_skeleton
signature = 0x10ec1965cadc101e
typeoffset = 0x00000000 0
COMPILE_UNIT<header overall offset = 0x00000126>:
< 0><0x00000014 GOFF=0x0000013a> DW_TAG_skeleton_unit <abbrev 1 ABGOFF = 0x0000007e count = 0x00000007>
DW_AT_ranges 0x000009b6 <form DW_FORM_sec_offset 23>
Offset of rnglists entries: 0x000009b6
Index of rnglist head : 6
rnglist head version : 5
Record count rnglist set : 293
Bytes this rnglist set : 1153
offset size : 4
address size : 8
CU DW_AT_low_pc (baseaddr): 0x00000000
CU DW_AT_addr_base : 0x00001f98
section offset CU rnglists: 0x000009aa
section length CU rnglists: 0x0000048d (1165)
secoff
[ 0] DW_RLE_startx_length 0x0000010c 0x00003511 0x000009b6
[ 0] start,end 0x00028d56 0x0002c267 0x000009b6
[ 1] DW_RLE_startx_length 0x000001de 0x0000000f 0x000009bb
[ 1] start,end 0x0001d463 0x0001d472 0x000009bb
...
[291] DW_RLE_startx_length 0x00000152 0x0000002f 0x00000e32
[291] start,end 0x000310aa 0x000310d9 0x00000e32
[292] DW_RLE_end_of_list 0x00000e36
[292] end of list 0x00000e36
DW_AT_low_pc 0x00000000 <form DW_FORM_addr 1>
DW_AT_stmt_list 0x0000a98b <form DW_FORM_sec_offset 23>
DW_AT_dwo_name CMakeFiles/cpptrace-lib.dir/src/cpptrace.cpp.dwo <form DW_FORM_strp 14>
DW_AT_comp_dir /mnt/c/Users/rifkin/home/projects/cpptrace/build <form DW_FORM_strp 14>
DW_AT_GNU_pubnames yes(1) <form DW_FORM_flag_present 25>
DW_AT_addr_base 0x00001f98 <form DW_FORM_sec_offset 23>
The subprogram DIE that lead to the first failure:
< 1><0x0001bdbf GOFF=0x0001bdbf> DW_TAG_subprogram <abbrev 263 ABGOFF = 0x00001350 count = 0x00000006>
DW_AT_name (indexed string: 0x0000048c)_GLOBAL__sub_I_cpptrace.cpp <form DW_FORM_strx 26>
DW_AT_artificial yes(1) <form DW_FORM_flag_present 25>
/mnt/c/Users/rifkin/home/projects/open-source/libdwarf-code/build/src/bin/dwarfdump/dwarfdump NO ENTRY: DW_FORM_addrx is a DW_DLV_NO_ENTRY? something is wrong.:
CU Name = (indexed string: 0x000001bc)/mnt/c/Users/rifkin/home/projects/cpptrace/src/cpptrace.cpp
CU Producer = (indexed string: 0x00000f1a)GNU C++17 13.2.0 -mtune=generic -march=x86-64 -gsplit-dwarf -gdwarf-5 -g -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -fasynchronous-unwind-tables -fstack-protector-strong -fstack-clash-protection -fcf-protection
DIE OFF = 0x0001bdbf GOFF = 0x0001bdbf, Low PC = unknown , High PC = unknown
DW_AT_low_pc
DW_AT_high_pc <offset-from-lowpc> 15 <form DW_FORM_data8 7>
DW_AT_frame_base len 0x0001: 0x9c: <form DW_FORM_exprloc 24>
DW_OP_call_frame_cfa
DW_AT_call_all_tail_calls yes(1) <form DW_FORM_flag_present 25>
I also included a zip of the objects in my earlier comment if it would be helpful to look at them directly.
OK. Found the latest attachment, downloaded. Problem reproduced. Thanks. Looking now.
Picking up signatures in dwarf_tied.c: the stopping condition of the loop accessing CU signatures was coded incorrectly. Stopped too soon. A problem with RNGLISTS remains.
Here is the change to dwarf_tied.c. Not yet committed .
diff --git a/src/lib/libdwarf/dwarf_tied.c b/src/lib/libdwarf/dwarf_tied.c
index 074623ea..e9921b2e 100644
--- a/src/lib/libdwarf/dwarf_tied.c
+++ b/src/lib/libdwarf/dwarf_tied.c
@@ -49,6 +49,7 @@
#include "dwarf_tsearch.h"
#include "dwarf_tied_decls.h"
+#if 0
void
_dwarf_dumpsig(const char *msg, Dwarf_Sig8 *sig,int lineno)
{
@@ -62,6 +63,7 @@ _dwarf_dumpsig(const char *msg, Dwarf_Sig8 *sig,int lineno)
}
printf(" line %d\n",lineno);
}
+#endif
void *
_dwarf_tied_make_entry(Dwarf_Sig8 *key, Dwarf_CU_Context val)
@@ -129,6 +131,7 @@ _dwarf_tied_destroy_free_node(void*nodep)
static int
_dwarf_loop_reading_debug_info_for_cu(
Dwarf_Debug tieddbg,
+ struct Dwarf_Tied_Entry_s *targsig,
Dwarf_Error *error)
{
/* We will not find tied signatures
@@ -207,11 +210,17 @@ _dwarf_loop_reading_debug_info_for_cu(
*(struct Dwarf_Tied_Data_s**) retval;
if (retent == entry) {
/* we added a record. */
- return DW_DLV_OK;
+ int res = _dwarf_tied_compare_function(
+ targsig,entry);
+ if (!res) {
+ /* Found match, stop looping */
+ return DW_DLV_OK;
+ }
+ continue;
} else {
/* found existing, no add */
free(entry);
- return DW_DLV_OK;
+ continue;
}
}
}
@@ -253,14 +262,14 @@ _dwarf_search_for_signature(Dwarf_Debug tieddbg,
*context_out = e2->dt_context;
return DW_DLV_OK;
}
-
/* We now ensure all tieddbg CUs signatures
are in the td_tied_search,
The caller is NOT doing
info section read operations
on the tieddbg in this (tied)dbg, so it
cannot goof up their _dwarf_next_cu_header*(). */
- res = _dwarf_loop_reading_debug_info_for_cu(tieddbg,error);
+ res = _dwarf_loop_reading_debug_info_for_cu(tieddbg,&entry,
+ error);
if (res == DW_DLV_ERROR) {
return res;
}
DWARF 5 in Table F.1 omitted mentions where to put DW_AT_rnglists_base and/or DW_AT_loclists_base in a CU DIE. And that attribute is missing from the skeleton data. However, there is sufficient data (already being read in) to calculate what the value of such a base would be. dwarfdump -i -vv prints it all out!
regression tests pass with the update posted above, committed and pushed to github. the rnglists/loclists issue remains, and will be dealt with next (not today, sorry).
Thanks so much for all the help with supporting this! I appreciate it immensely.
Pushed these and other fixes to .debug_rnglists and .debug_loclists. Dwarfdump does a more useful job of reporting those sections now.
This is fixed. Closing.
Thank you so much!
I'm running into an odd issue where
dwarf_lowpc
is returningDW_DLV_NO_ENTRY
on a die that has aDW_AT_low_pc
attribute:For additional context, I'm working with split dwarf objects and this die is located in a .dwo file but I have tied with the appropriate executable/.so debug. The .dwo is cpptrace.cpp.dwo and the .so is libcpptrace.so which references the .dwo as
I haven't had this issue for a couple other cases of working with dies in .dwo files. I can try to provide additional information as needed.