From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14077 invoked by alias); 21 Mar 2018 02:34:13 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Received: (qmail 14062 invoked by uid 89); 21 Mar 2018 02:34:12 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_PASS,URIBL_RED autolearn=ham version=3.3.2 spammy= X-HELO: mail-pf0-f177.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=G/0hF5ZiLNlLSsf3hhmaOMeT8zHGcQ/EnsbkrOjrV38=; b=O1zRrriI9jbp1XUW+Y0lojSf7/IioFhp6E8fic0z8ezsjZ7e4hwBg6h3yiKFtNDxhd aLa5zv8DZkSjemdSJgIljWXfsrhTfQCIRePRedTsXjk4K94Q6YLPDufN5V1LPQwXJkbk vOnd/U6pGypmxw55zJ8Md56g5veSq+0dRQv9sswmhcdAy99AnrIRd35eL6tt6PlQes0p XfT+CXvRqXRIiwX/bUUFI1Ks7gEOXGB1Zpe2zFB3UIwM6XnMoeJqNe54wXGEFMht8WMu TT+Qlgz9/PVVeZcBon6Ltc5XpineU3cBymHoRvO/jPRcW4CtIs54cTGJVnYV/3kbpHg3 pR4g== X-Gm-Message-State: AElRT7F74VKm4Tmn13CDF+zAhbIDFylNZCE+mJCS6gGNLwLaXT21Imjz mk/8TCTnxqTyPFt/6mnBdvXSsAtjXho= X-Google-Smtp-Source: AG47ELskEjzwdaChb+LN4Rhw0d5brOFTI/k6aNAi2dM5lASRzx0/biYUw9iQX8OGJWTkEi+1bgldfQ== X-Received: by 10.99.127.75 with SMTP id p11mr13417610pgn.392.1521599647456; Tue, 20 Mar 2018 19:34:07 -0700 (PDT) Subject: Re: Use x86_64 backtrace as generic version To: libc-alpha@sourceware.org References: From: Adhemerval Zanella Message-ID: Date: Wed, 21 Mar 2018 02:34:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-SW-Source: 2018-03/txt/msg00498.txt.bz2 On 21/03/2018 09:21, Joseph Myers wrote: > No glibc configuration uses the present debug/backtrace.c, whereas > several #include the x86_64 version. The x86_64 version is > effectively a generic one (using _Unwind_Backtrace from libgcc, which > works much more reliably than the built-in functions used by > debug/backtrace.c). This patch moves it to debug/backtrace.c and > removes all the #includes of the x86_64 version from other > architectures which are no longer required. > > I do not know whether all the other architecture-specific backtrace > implementations that are based on _Unwind_Backtrace are required, or > whether, where their differences from the generic version do something > useful, suitable hooks could be added to the generic version to reduce > the duplication involved. With this change we still have i386, sparc, m68k, arm, and s390 which uses libgcc based backtrace implementation. I will check if i386, sparc, and arm can be simplified. > > Tested with build-many-glibcs.py that installed stripped shared > libraries are unchanged by this patch. > > 2018-03-20 Joseph Myers > > * sysdeps/x86_64/backtrace.c: Move to .... > * debug/backtrace.c: ... here. > * sysdeps/aarch64/backtrace.c: Remove file. > * sysdeps/alpha/backtrace.c: Likewise. > * sysdeps/hppa/backtrace.c: Likewise. > * sysdeps/ia64/backtrace.c: Likewise. > * sysdeps/mips/backtrace.c: Likewise. > * sysdeps/nios2/backtrace.c: Likewise. > * sysdeps/riscv/backtrace.c: Likewise. > * sysdeps/sh/backtrace.c: Likewise. > * sysdeps/tile/backtrace.c: Likewise. LGTM. Reviewed-by: Adhemerval Zanella. > > diff --git a/debug/backtrace.c b/debug/backtrace.c > index 60d4a15..d423cc0 100644 > --- a/debug/backtrace.c > +++ b/debug/backtrace.c > @@ -1,7 +1,7 @@ > -/* Return backtrace of current program state. Generic version. > - Copyright (C) 1998-2018 Free Software Foundation, Inc. > +/* Return backtrace of current program state. > + Copyright (C) 2003-2018 Free Software Foundation, Inc. > This file is part of the GNU C Library. > - Contributed by Ulrich Drepper , 1998. > + Contributed by Jakub Jelinek , 2003. > > The GNU C Library is free software; you can redistribute it and/or > modify it under the terms of the GNU Lesser General Public > @@ -17,74 +17,118 @@ > License along with the GNU C Library; if not, see > . */ > > +#include > +#include > #include > -#include > -#include > -#include > -#include > - > -/* This implementation assumes a stack layout that matches the defaults > - used by gcc's `__builtin_frame_address' and `__builtin_return_address' > - (FP is the frame pointer register): > - > - +-----------------+ +-----------------+ > - FP -> | previous FP --------> | previous FP ------>... > - | | | | > - | return address | | return address | > - +-----------------+ +-----------------+ > - > - */ > - > -/* Get some notion of the current stack. Need not be exactly the top > - of the stack, just something somewhere in the current frame. */ > -#ifndef CURRENT_STACK_FRAME > -# define CURRENT_STACK_FRAME ({ char __csf; &__csf; }) > -#endif > +#include > +#include > +#include > > -/* By default we assume that the stack grows downward. */ > -#ifndef INNER_THAN > -# define INNER_THAN < > -#endif > +struct trace_arg > +{ > + void **array; > + _Unwind_Word cfa; > + int cnt; > + int size; > +}; > + > +#ifdef SHARED > +static _Unwind_Reason_Code (*unwind_backtrace) (_Unwind_Trace_Fn, void *); > +static _Unwind_Ptr (*unwind_getip) (struct _Unwind_Context *); > +static _Unwind_Word (*unwind_getcfa) (struct _Unwind_Context *); > +static void *libgcc_handle; > + > + > +/* Dummy version in case libgcc_s does not contain the real code. */ > +static _Unwind_Word > +dummy_getcfa (struct _Unwind_Context *ctx __attribute__ ((unused))) > +{ > + return 0; > +} > > -/* By default assume the `next' pointer in struct layout points to the > - next struct layout. */ > -#ifndef ADVANCE_STACK_FRAME > -# define ADVANCE_STACK_FRAME(next) ((struct layout *) (next)) > -#endif > > -/* By default, the frame pointer is just what we get from gcc. */ > -#ifndef FIRST_FRAME_POINTER > -# define FIRST_FRAME_POINTER __builtin_frame_address (0) > +static void > +init (void) > +{ > + libgcc_handle = __libc_dlopen (LIBGCC_S_SO); > + > + if (libgcc_handle == NULL) > + return; > + > + unwind_backtrace = __libc_dlsym (libgcc_handle, "_Unwind_Backtrace"); > + unwind_getip = __libc_dlsym (libgcc_handle, "_Unwind_GetIP"); > + if (unwind_getip == NULL) > + unwind_backtrace = NULL; > + unwind_getcfa = (__libc_dlsym (libgcc_handle, "_Unwind_GetCFA") > + ?: dummy_getcfa); > +} > +#else > +# define unwind_backtrace _Unwind_Backtrace > +# define unwind_getip _Unwind_GetIP > +# define unwind_getcfa _Unwind_GetCFA > #endif > > +static _Unwind_Reason_Code > +backtrace_helper (struct _Unwind_Context *ctx, void *a) > +{ > + struct trace_arg *arg = a; > + > + /* We are first called with address in the __backtrace function. > + Skip it. */ > + if (arg->cnt != -1) > + { > + arg->array[arg->cnt] = (void *) unwind_getip (ctx); > + > + /* Check whether we make any progress. */ > + _Unwind_Word cfa = unwind_getcfa (ctx); > + > + if (arg->cnt > 0 && arg->array[arg->cnt - 1] == arg->array[arg->cnt] > + && cfa == arg->cfa) > + return _URC_END_OF_STACK; > + arg->cfa = cfa; > + } > + if (++arg->cnt == arg->size) > + return _URC_END_OF_STACK; > + return _URC_NO_REASON; > +} > + > int > __backtrace (void **array, int size) > { > - struct layout *current; > - void *top_frame; > - void *top_stack; > - int cnt = 0; > + struct trace_arg arg = { .array = array, .cfa = 0, .size = size, .cnt = -1 }; > > - top_frame = FIRST_FRAME_POINTER; > - top_stack = CURRENT_STACK_FRAME; > + if (size <= 0) > + return 0; > > - /* We skip the call to this function, it makes no sense to record it. */ > - current = ((struct layout *) top_frame); > - while (cnt < size) > - { > - if ((void *) current INNER_THAN top_stack > - || !((void *) current INNER_THAN __libc_stack_end)) > - /* This means the address is out of range. Note that for the > - toplevel we see a frame pointer with value NULL which clearly is > - out of range. */ > - break; > +#ifdef SHARED > + __libc_once_define (static, once); > > - array[cnt++] = current->return_address; > + __libc_once (once, init); > + if (unwind_backtrace == NULL) > + return 0; > +#endif > > - current = ADVANCE_STACK_FRAME (current->next); > - } > + unwind_backtrace (backtrace_helper, &arg); > > - return cnt; > + /* _Unwind_Backtrace seems to put NULL address above > + _start. Fix it up here. */ > + if (arg.cnt > 1 && arg.array[arg.cnt - 1] == NULL) > + --arg.cnt; > + return arg.cnt != -1 ? arg.cnt : 0; > } > weak_alias (__backtrace, backtrace) > libc_hidden_def (__backtrace) > + > + > +#ifdef SHARED > +/* Free all resources if necessary. */ > +libc_freeres_fn (free_mem) > +{ > + unwind_backtrace = NULL; > + if (libgcc_handle != NULL) > + { > + __libc_dlclose (libgcc_handle); > + libgcc_handle = NULL; > + } > +} > +#endif > diff --git a/sysdeps/aarch64/backtrace.c b/sysdeps/aarch64/backtrace.c > deleted file mode 100644 > index 27ce597..0000000 > --- a/sysdeps/aarch64/backtrace.c > +++ /dev/null > @@ -1 +0,0 @@ > -#include > diff --git a/sysdeps/alpha/backtrace.c b/sysdeps/alpha/backtrace.c > deleted file mode 100644 > index 27ce597..0000000 > --- a/sysdeps/alpha/backtrace.c > +++ /dev/null > @@ -1 +0,0 @@ > -#include > diff --git a/sysdeps/hppa/backtrace.c b/sysdeps/hppa/backtrace.c > deleted file mode 100644 > index 27ce597..0000000 > --- a/sysdeps/hppa/backtrace.c > +++ /dev/null > @@ -1 +0,0 @@ > -#include > diff --git a/sysdeps/ia64/backtrace.c b/sysdeps/ia64/backtrace.c > deleted file mode 100644 > index 27ce597..0000000 > --- a/sysdeps/ia64/backtrace.c > +++ /dev/null > @@ -1 +0,0 @@ > -#include > diff --git a/sysdeps/mips/backtrace.c b/sysdeps/mips/backtrace.c > deleted file mode 100644 > index 27ce597..0000000 > --- a/sysdeps/mips/backtrace.c > +++ /dev/null > @@ -1 +0,0 @@ > -#include > diff --git a/sysdeps/nios2/backtrace.c b/sysdeps/nios2/backtrace.c > deleted file mode 100644 > index 27ce597..0000000 > --- a/sysdeps/nios2/backtrace.c > +++ /dev/null > @@ -1 +0,0 @@ > -#include > diff --git a/sysdeps/riscv/backtrace.c b/sysdeps/riscv/backtrace.c > deleted file mode 100644 > index 27ce597..0000000 > --- a/sysdeps/riscv/backtrace.c > +++ /dev/null > @@ -1 +0,0 @@ > -#include > diff --git a/sysdeps/sh/backtrace.c b/sysdeps/sh/backtrace.c > deleted file mode 100644 > index 4f3eafb..0000000 > --- a/sysdeps/sh/backtrace.c > +++ /dev/null > @@ -1 +0,0 @@ > -#include "../x86_64/backtrace.c" > diff --git a/sysdeps/tile/backtrace.c b/sysdeps/tile/backtrace.c > deleted file mode 100644 > index 27ce597..0000000 > --- a/sysdeps/tile/backtrace.c > +++ /dev/null > @@ -1 +0,0 @@ > -#include > diff --git a/sysdeps/x86_64/backtrace.c b/sysdeps/x86_64/backtrace.c > deleted file mode 100644 > index d423cc0..0000000 > --- a/sysdeps/x86_64/backtrace.c > +++ /dev/null > @@ -1,134 +0,0 @@ > -/* Return backtrace of current program state. > - Copyright (C) 2003-2018 Free Software Foundation, Inc. > - This file is part of the GNU C Library. > - Contributed by Jakub Jelinek , 2003. > - > - The GNU C Library is free software; you can redistribute it and/or > - modify it under the terms of the GNU Lesser General Public > - License as published by the Free Software Foundation; either > - version 2.1 of the License, or (at your option) any later version. > - > - The GNU C Library is distributed in the hope that it will be useful, > - but WITHOUT ANY WARRANTY; without even the implied warranty of > - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > - Lesser General Public License for more details. > - > - You should have received a copy of the GNU Lesser General Public > - License along with the GNU C Library; if not, see > - . */ > - > -#include > -#include > -#include > -#include > -#include > -#include > - > -struct trace_arg > -{ > - void **array; > - _Unwind_Word cfa; > - int cnt; > - int size; > -}; > - > -#ifdef SHARED > -static _Unwind_Reason_Code (*unwind_backtrace) (_Unwind_Trace_Fn, void *); > -static _Unwind_Ptr (*unwind_getip) (struct _Unwind_Context *); > -static _Unwind_Word (*unwind_getcfa) (struct _Unwind_Context *); > -static void *libgcc_handle; > - > - > -/* Dummy version in case libgcc_s does not contain the real code. */ > -static _Unwind_Word > -dummy_getcfa (struct _Unwind_Context *ctx __attribute__ ((unused))) > -{ > - return 0; > -} > - > - > -static void > -init (void) > -{ > - libgcc_handle = __libc_dlopen (LIBGCC_S_SO); > - > - if (libgcc_handle == NULL) > - return; > - > - unwind_backtrace = __libc_dlsym (libgcc_handle, "_Unwind_Backtrace"); > - unwind_getip = __libc_dlsym (libgcc_handle, "_Unwind_GetIP"); > - if (unwind_getip == NULL) > - unwind_backtrace = NULL; > - unwind_getcfa = (__libc_dlsym (libgcc_handle, "_Unwind_GetCFA") > - ?: dummy_getcfa); > -} > -#else > -# define unwind_backtrace _Unwind_Backtrace > -# define unwind_getip _Unwind_GetIP > -# define unwind_getcfa _Unwind_GetCFA > -#endif > - > -static _Unwind_Reason_Code > -backtrace_helper (struct _Unwind_Context *ctx, void *a) > -{ > - struct trace_arg *arg = a; > - > - /* We are first called with address in the __backtrace function. > - Skip it. */ > - if (arg->cnt != -1) > - { > - arg->array[arg->cnt] = (void *) unwind_getip (ctx); > - > - /* Check whether we make any progress. */ > - _Unwind_Word cfa = unwind_getcfa (ctx); > - > - if (arg->cnt > 0 && arg->array[arg->cnt - 1] == arg->array[arg->cnt] > - && cfa == arg->cfa) > - return _URC_END_OF_STACK; > - arg->cfa = cfa; > - } > - if (++arg->cnt == arg->size) > - return _URC_END_OF_STACK; > - return _URC_NO_REASON; > -} > - > -int > -__backtrace (void **array, int size) > -{ > - struct trace_arg arg = { .array = array, .cfa = 0, .size = size, .cnt = -1 }; > - > - if (size <= 0) > - return 0; > - > -#ifdef SHARED > - __libc_once_define (static, once); > - > - __libc_once (once, init); > - if (unwind_backtrace == NULL) > - return 0; > -#endif > - > - unwind_backtrace (backtrace_helper, &arg); > - > - /* _Unwind_Backtrace seems to put NULL address above > - _start. Fix it up here. */ > - if (arg.cnt > 1 && arg.array[arg.cnt - 1] == NULL) > - --arg.cnt; > - return arg.cnt != -1 ? arg.cnt : 0; > -} > -weak_alias (__backtrace, backtrace) > -libc_hidden_def (__backtrace) > - > - > -#ifdef SHARED > -/* Free all resources if necessary. */ > -libc_freeres_fn (free_mem) > -{ > - unwind_backtrace = NULL; > - if (libgcc_handle != NULL) > - { > - __libc_dlclose (libgcc_handle); > - libgcc_handle = NULL; > - } > -} > -#endif >