This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]