This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
Re: DWARF Information not Used with Wildcards
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.
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).
Also could you show the producer attribute of the CU DIE?
I wonder which version of GCC you are using (or some other compiler).
Thanks,
Mark