libunwind-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Libunwind-devel] Backtrace performance on x86-64 based on Dwarf inf


From: Milian Wolff
Subject: Re: [Libunwind-devel] Backtrace performance on x86-64 based on Dwarf info
Date: Mon, 25 Aug 2014 13:11:27 +0200
User-agent: KMail/4.14 (Linux/3.16.1-1-ARCH; KDE/4.14.0; x86_64; ; )

On Monday 25 August 2014 11:46:12 Milian Wolff wrote:
> On Thursday 19 June 2014 23:50:25 Lassi Tuura wrote:
> > Hey,
> 
> Hey Lassi, Arun.
> 
> I want to revive this thread after my long absence in the hope to get the
> situation improved upstream. Locally, I've been running with the patch of
> the previous mail for some time now and it works very well in my case.
> > Thanks for testing that. Note though that as the comment immediately above
> > says, x86_64 ABI says the last frame should have null RBP (IIRC, that's
> > 3.4.1 Initial Stack and Register State). Can you possibly find out why
> > that doesn't hold on your platform?
> 
> Do you have any suggestions on how to do that? I.e. what should I look at?
> Specific compile options for libc? You can find the PKGBUILD that is used on
> ArchLinux here:
> 
> https://projects.archlinux.org/svntogit/packages.git/tree/trunk?h=packages/g
> libc
> 
> That contains the configure invocation with all its arguments and the
> patches that are applied previously.
> 
> > The code I was thinking about is apply_reg_state in src/dwarf/Gparser.c
> > where the DWARF_IS_NULL_LOC (c->loc[c->ret_addr_column]) conditions should
> > have kicked in to set RIP for the next step to 0, which I vaguely recall
> > caused the unwind to terminate at that step. But maybe there was a change
> > to allow unwinding to continue with RIP == 0. (Arun do you recall details
> > on that? For example
> > http://git.savannah.gnu.org/gitweb/?p=libunwind.git;a=commitdiff;h=d04dc94
> > cc 2b0141f06ed9de1665ab89a3f549e0b - I vaguely recall we talked about it.)
>
> Any news on that Arun? I'll also try to figure out whats going on and why
> this is not kicking in.

Quick update, I looked at it a bit more with the following test program:

~~~~~~~~~~~~~~~~
#include <stdio.h>

#define UNW_LOCAL_ONLY
#include <libunwind.h>

int main()
{
    const int MAX_SIZE = 128;
    void* data[MAX_SIZE];
    for (int repeat = 0; repeat < 2; ++repeat) {
        int size = unw_backtrace(data, MAX_SIZE);
        printf("\ntrace size: %d\n\n", size);
        for (int i = 0; i < size; ++i) {
            printf("%p\n", data[i]);
        }
        printf("\n");
    }
    return 0;
}
~~~~~~~~~~~~~~~~

Running it with UNW_DEBUG_LEVEL=15 env var set, I get the output you find 
attached in original.log. I've added debug output to apply_reg_state when the 
IP set set to zero, i.e.: apply_reg_state:818: SETTING IP TO ZERO

You'll see that the IP _is_ set to zero but unwinding is continued thereafter,
even though "DWARF spec says undefined return address location means end of 
stack." (dwarf/Gparser.c). The garbage "0" ip is returned at the end.

With the patch to also check for this in x86_64/Gstep.c applied, the output 
changes to patched.log and everything behaves correctly, as far as I can see. 
The garbage "0" ip is skipped, i.e. unwind stops properly and everything is 
cached and fast.

So, can we get this patch in, or should we add a "last_frame" to dwarf_cursor 
which is set to 1 when the return address location is undefined? This would 
mean changes all over the place though, something which I'd not be comfortable 
with as I cannot test other architectures easily. Esp. the question whether 
checking for ip == 0 is valid on e.g. x86 or not is something I cannot decide.

Bye
-- 
Milian Wolff
address@hidden
http://milianw.de

Attachment: original.log
Description: Text Data

Attachment: patched.log
Description: Text Data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]