This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
Re: DWARF Information not Used with Wildcards
Hi Mark,
> Am 22.04.2018 um 22:44 schrieb Mark Wielaard <mark@klomp.org>:
>
> Hi Torsten,
>
> On Sun, 2018-04-22 at 09:27 +0200, Torsten Polle wrote:
>> Am 15.04.2018 um 00:52 schrieb Torsten Polle <Torsten.Polle@gmx.de>
>>> Am 10.04.2018 um 22:40 schrieb Torsten Polle
>>>>> Am 10.04.2018 um 16:37 schrieb Mark Wielaard <mark@klomp.org>:
>>>>>
>>>>> On Mon, 2018-04-09 at 22:32 +0200, Torsten Polle wrote:
>>>>>> I’ve a problem with commit
>>>>>> 5ef0c24456e3279cda2f444e9db0a3292388cdd7.
>>>>>
>>>>> commit 5ef0c24456e3279cda2f444e9db0a3292388cdd7
>>>>> Author: Mark Wielaard <mark@klomp.org>
>>>>> Date: Thu Feb 22 10:54:36 2018 +0100
>>>>>
>>>>> dwflpp::function_entrypc if entry or low pc isn't given use base or start.
>>>>>
>>>>> On Fedora rawhide a kernel compiled with GCC8 sometimes has subprograms
>>>>> without an entry or low pc attribute, but with a ranges attribute. In that
>>>>> case assume the base address or first start address of the range is the
>>>>> entry pc to set a probe on.
>>>>>
>>>>> So that is mine. Sorry about that.
>>>>>
>>>>>> When the commit is applied, the output of running the command
>>>>>> (simplified)
>>>>>> stap -L 'process("/lib64/libcarplay-plugin-
>>>>>> core.so").function("*").call' | grep RTPJitterBufferRead
>>>>>> yields
>>>>>> process("/lib64/libcarplay-plugin-
>>>>>> core.so").function("RTPJitterBufferRead").call
>>>>>>
>>>>>> Seemingly, the DWARF information is ignored.
>>>>>>
>>>>>> When I revert the commit and run the same command, I get the
>>>>>> following output
>>>>>> process("/lib64/libcarplay-plugin-core.so").function("RTPJitterBuffer
>>>>>> Read@Sources/AirPlayUtils.c:1261").call $ctx:RTPJitterBufferContext*
>>>>>> $inBuffer:void* $inLen:size_t
>>>>>>
>>>>>> What’s strange is that
>>>>>> stap -L 'process("/lib64/libcarplay-plugin-
>>>>>> core.so").function("RTPJitterBufferRead").call‘
>>>>>> shows the correct output in both cases.
>>>>>
>>>>> I haven't had time to replicate and study this yet. What is
>>>>> /lib64/libcarplay-plugin-core.so?
>>>>>
>>>>> But my guess is that we now erroneously pick up a function
>>>>> declaration
>>>>> instead of a function definition.
>>>>>
>>>>> Could you show the eu-readelf --debug-dump=info DIEs for the
>>>>> RTPJitterBufferRead function in libcarplay-plugin-core.so?
>>>>>
>>> I digged into this issue further.
>>>
>>> The failure is caused by xpc_dictionary_create_compat() [1]. This
>>> function causes an exception at the following place:
>>>
>>> dwflpp::resolve_prologue_endings()
>>> {
>>> ...
>>> for(auto it = funcs.begin(); it != funcs.end(); it++)
>>> {
>>> Dwarf_Addr entrypc = it->entrypc;
>>> Dwarf_Addr highpc; // NB: highpc is exclusive:
>>> [entrypc,highpc)
>>> DWFL_ASSERT ("dwarf_highpc", dwarf_highpc (& it->die,
>>> & highpc));
>>> ...
>>> }
>>>
>>> As a result of the exception query_cu() returns DWARF_CB_ABORT,
>>> which in turn makes dwflpp::iterate_over_cus<void>() bail out
>>> prematurely. Not all CUs are traversed, which includes the one that
>>> holds RTPJitterBufferRead().
>>>
>>> Without the commit, dwflpp::function_entrypc() simply returns
>>> „bad“. With the commit, dwflpp::function_entrypc() returns „true“.
>
> aha. good observation.
Took me a while to figure this out. ;-) Used SystemTap to debug SystemTap though.
> So, the DWFL_ASSERT apparently triggers because the function is
> accepted by dwflpp::function_entrypc(), but wasn't before, since it
> doesn't have a simple low_pc/high_pc range.
>
> I think this is a latent bug because the function assumes the code
> range for a function is just one block, but functions could be split in
> multiple ranges (for example a compiler might put the "cold" part of a
> function somewhere else than the "hot" part of a function).
>
> The assert seem bogus. The function really shouldn't get and compare
> against highpc. And everywhere this function checks "addr >= highpc" it
> really should call dwarf_haspc (&it->die, addr).
>
>>> [1] Excerpt for xpc_dictionary_create_compat
>>>
>>> [ a68a7] subprogram
>>> external (flag_present)
>>> name (strp)
>>> "xpc_dictionary_create_compat"
>>> decl_file (data1) 1
>>> decl_line (data1) 107
>>> prototyped (flag_present)
>>> type (ref4) [ a5ba1]
>>> sibling (ref4) [ a68d8]
>>> [ a68b6] formal_parameter
>>> name (strp) "inKeys"
>>> decl_file (data1) 1
>>> decl_line (data1) 107
>>> type (ref4) [ a68d8]
>>> [ a68c1] formal_parameter
>>> name (strp) "inValues"
>>> decl_file (data1) 1
>>> decl_line (data1) 107
>>> type (ref4) [ a68de]
>>> [ a68cc] formal_parameter
>>> name (strp) "inCount"
>>> decl_file (data1) 1
>>> decl_line (data1) 107
>>> type (ref4) [ a52f6]
>>> [ a68d8] pointer_type
>>> byte_size (data1) 8
>>> type (ref4) [ a57a8]
>>> [ a68de] pointer_type
>>> byte_size (data1) 8
>>> type (ref4) [ a5bac]
>>
>> any comments on my observations? Is there anything more you need to
>> know?
>
> Are you sure this is the DIE that describes the function in
> dwflpp::resolve_prologue_endings? I am surprised since this is just the
> prototype of the function and has no associated address at all. I would
> expect a subprogram or inlined_subroutine that has at least a range (if
> not a low/high_pc).
This is all I could find. I did a grep for „xpc_dictionary_create_compat“.
Checked with objdump and normal readelf as well. The result is the same.
> Also could you show the producer attribute of the CU DIE?
> I wonder which version of GCC you are using (or some other compiler).
It’s GCC: GNU C99 6.2.0 -m64 -march=core2 -msse3 -mtune=generic -mfpmath=sse -msgxx-glibc -g -O2 -std=gnu11 -std=gnu99 -ffunction-sections -fdata-sections -feliminate-unused-debug-types -fpic
> Thanks,
> Mark
Thanks,
Torsten