diff mbox

Backtrace library [1/3]

Message ID mcroblcp3ws.fsf@google.com
State New
Headers show

Commit Message

Ian Lance Taylor Sept. 11, 2012, 10:53 p.m. UTC
I have finished the initial implementation of the backtrace library I
proposed at http://gcc.gnu.org/ml/gcc/2012-08/msg00317.html .  I've
separated the work into three patches.  These patches only implement the
backtrace library itself; actual use of the library will follow in
separate patches.

This initial implementation only supports ELF and DWARF.  The library is
designed to work correctly for other cases, in the sense that it will
report that it can not find any backtrace information.  The library is
designed to make it straightforward to add support for other object file
formats and debugging formats.  My intent is to commit the library with
ELF/DWARF support and then support other people in extending it.  In
particular, adding support for Mach-O and PE with DWARF should be
simple.

This patch is the interface to and configury of libbacktrace.  I've
separated these out as the parts of libbacktrace that require the most
review.  The interface to libbacktrace is in the file backtrace.h.  This
is what callers will use.  The file backtrace-supported.h is also
available so that programs can see whether calling the backtrace library
will work at all.

The configury is fairly standard.  Note that libbacktrace is built as
both a host library (to link into the compilers) and as a target library
(to link into libgo and possibly other libraries).

Bootstrapped on x86_64-unknown-linux-gnu in conjunction with the other
two patches.  OK for mainline?

Ian


2012-09-11  Ian Lance Taylor  <iant@google.com>

	* Initial implementation.

Comments

Gabriel Dos Reis Sept. 11, 2012, 11:01 p.m. UTC | #1
On Tue, Sep 11, 2012 at 5:53 PM, Ian Lance Taylor <iant@google.com> wrote:

> This patch is the interface to and configury of libbacktrace.  I've
> separated these out as the parts of libbacktrace that require the most
> review.  The interface to libbacktrace is in the file backtrace.h.  This
> is what callers will use.  The file backtrace-supported.h is also
> available so that programs can see whether calling the backtrace library
> will work at all.

So, you've settled on a C interface?  A C++ interface would have been
native for other open source projects that are C++ oriented...

-- Gaby
Chris Lattner Sept. 11, 2012, 11:07 p.m. UTC | #2
On Sep 11, 2012, at 3:53 PM, Ian Lance Taylor <iant@google.com> wrote:

> I have finished the initial implementation of the backtrace library I
> proposed at http://gcc.gnu.org/ml/gcc/2012-08/msg00317.html .  I've
> separated the work into three patches.  These patches only implement the
> backtrace library itself; actual use of the library will follow in
> separate patches.

Hi Ian,

I have no specific comment on the implementation of this library, but:
> 
> +/* Get a full stack backtrace.  SKIP is the number of frames to skip;
> +   passing 0 will start the trace with the function calling backtrace.
> +   DATA is passed to the callback routine.  If any call to CALLBACK
> +   returns a non-zero value, the stack backtrace stops, and backtrace
> +   returns that value; this may be used to limit the number of stack
> +   frames desired.  If all calls to CALLBACK return 0, backtrace
> +   returns 0.  The backtrace function will make at least one call to
> +   either CALLBACK or ERROR_CALLBACK.  This function requires debug
> +   info for the executable.  */
> +
> +extern int backtrace (int skip, backtrace_callback callback,
> +		      backtrace_error_callback error_callback, void *data);

FYI, "backtrace" is a well-known function provide by glibc (and other libc's).  It might be best to pick another name.

-Chris
Ian Lance Taylor Sept. 11, 2012, 11:08 p.m. UTC | #3
On Tue, Sep 11, 2012 at 4:01 PM, Gabriel Dos Reis
<gdr@integrable-solutions.net> wrote:
> On Tue, Sep 11, 2012 at 5:53 PM, Ian Lance Taylor <iant@google.com> wrote:
>
>> This patch is the interface to and configury of libbacktrace.  I've
>> separated these out as the parts of libbacktrace that require the most
>> review.  The interface to libbacktrace is in the file backtrace.h.  This
>> is what callers will use.  The file backtrace-supported.h is also
>> available so that programs can see whether calling the backtrace library
>> will work at all.
>
> So, you've settled on a C interface?  A C++ interface would have been
> native for other open source projects that are C++ oriented...

Yes, a C interface is convenient for libgo, and of course is generally
usable.  We can certainly layer a C++ interface on top if it seems
useful.

The interface is somewhat constrained in that, on systems that support
anonymous mmap, it does not call malloc.  That makes it possible to do
a symbolic backtrace from a signal handler.

Ian
Gabriel Dos Reis Sept. 11, 2012, 11:23 p.m. UTC | #4
On Tue, Sep 11, 2012 at 6:08 PM, Ian Lance Taylor <iant@google.com> wrote:
> On Tue, Sep 11, 2012 at 4:01 PM, Gabriel Dos Reis
> <gdr@integrable-solutions.net> wrote:
>> On Tue, Sep 11, 2012 at 5:53 PM, Ian Lance Taylor <iant@google.com> wrote:
>>
>>> This patch is the interface to and configury of libbacktrace.  I've
>>> separated these out as the parts of libbacktrace that require the most
>>> review.  The interface to libbacktrace is in the file backtrace.h.  This
>>> is what callers will use.  The file backtrace-supported.h is also
>>> available so that programs can see whether calling the backtrace library
>>> will work at all.
>>
>> So, you've settled on a C interface?  A C++ interface would have been
>> native for other open source projects that are C++ oriented...
>
> Yes, a C interface is convenient for libgo, and of course is generally
> usable.  We can certainly layer a C++ interface on top if it seems
> useful.
>
> The interface is somewhat constrained in that, on systems that support
> anonymous mmap, it does not call malloc.  That makes it possible to do
> a symbolic backtrace from a signal handler.

I actually liked the uses of mmap where possible -- as opposed to malloc.
(which is what I do in my own projects.)

I would have expected a C interface layer over a C++ interface, as opposed
to the other around....

-- gaby
Ian Lance Taylor Sept. 11, 2012, 11:24 p.m. UTC | #5
On Tue, Sep 11, 2012 at 4:07 PM, Chris Lattner <clattner@apple.com> wrote:
>
> FYI, "backtrace" is a well-known function provide by glibc (and other libc's).  It might be best to pick another name.

Good point.  Thanks.  I renamed it to backtrace_full.  I've included
the updated backtrace.h here.  The other changes are mechanical.

Ian

/* backtrace.h -- Public header file for stack backtrace library.
   Copyright (C) 2012 Free Software Foundation, Inc.
   Written by Ian Lance Taylor, Google.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

    (1) Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.

    (2) Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in
    the documentation and/or other materials provided with the
    distribution.

    (3) The name of the author may not be used to
    endorse or promote products derived from this software without
    specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.  */

#ifndef BACKTRACE_H
#define BACKTRACE_H

#include <stddef.h>
#include <stdint.h>
#include <stdio.h>

#ifdef __cplusplus
extern "C" {
#endif

/* The backtrace code needs to open the executable file in order to
   find the debug info.  On systems that do not support
   /proc/self/exe, the program using the backtrace library needs to
   tell the backtrace library the name of the executable to open.  It
   does so by calling backtrace_set_executable_name.  The FILENAME
   argument must point to a permanent buffer.  */

extern void backtrace_set_executable_name (const char *filename);

/* The type of the callback argument to the backtrace_full function.
   DATA is the argument passed to backtrace_full.  PC is the program
   counter.  FILENAME is the name of the file containing PC, or NULL
   if not available.  LINENO is the line number in FILENAME containing
   PC, or 0 if not available.  FUNCTION is the name of the function
   containing PC, or NULL if not available.  This should return 0 to
   continuing tracing.  The FILENAME and FUNCTION buffers may become
   invalid after this function returns.  */

typedef int (*backtrace_full_callback) (void *data, uintptr_t pc,
					const char *filename, int lineno,
					const char *function);

/* The type of the error callback argument to backtrace functions.
   This function, if not NULL, will be called for certain error cases.
   The DATA argument is passed to the function that calls this one.
   The MSG argument is an error message.  The ERRNUM argument, if
   greater than 0, holds an errno value.  The MSG buffer may become
   invalid after this function returns.

   As a special case, the ERRNUM argument will be passed as -1 if no
   debug info can be found for the executable, but the function
   requires debug info (e.g., backtrace_full, backtrace_pcinfo).  The
   MSG in this case will be something along the lines of "no debug
   info".  Similarly, ERRNUM will be passed as -1 if there is no
   symbol table, but the function requires a symbol table (e.g.,
   backtrace_syminfo).  This may be used as a signal that some other
   approach should be tried.  */

typedef void (*backtrace_error_callback) (void *data, const char *msg,
					  int errnum);

/* Get a full stack backtrace.  SKIP is the number of frames to skip;
   passing 0 will start the trace with the function calling
   backtrace_full.  DATA is passed to the callback routine.  If any
   call to CALLBACK returns a non-zero value, the stack backtrace
   stops, and backtrace returns that value; this may be used to limit
   the number of stack frames desired.  If all calls to CALLBACK
   return 0, backtrace returns 0.  The backtrace_full function will
   make at least one call to either CALLBACK or ERROR_CALLBACK.  This
   function requires debug info for the executable.  */

extern int backtrace_full (int skip, backtrace_full_callback callback,
			   backtrace_error_callback error_callback,
			   void *data);

/* The type of the callback argument to the backtrace_simple function.
   DATA is the argument passed to simple_backtrace.  PC is the program
   counter.  This should return 0 to continue tracing.  */

typedef int (*backtrace_simple_callback) (void *data, uintptr_t pc);

/* Get a simple backtrace.  SKIP is the number of frames to skip, as
   in backtrace.  DATA is passed to the callback routine.  If any call
   to CALLBACK returns a non-zero value, the stack backtrace stops,
   and backtrace_simple returns that value.  Otherwise
   backtrace_simple returns 0.  The backtrace_simple function will
   make at least one call to either CALLBACK or ERROR_CALLBACK.  This
   function does not require any debug info for the executable.  */

extern int backtrace_simple (int skip, backtrace_simple_callback callback,
			     backtrace_error_callback error_callback,
			     void *data);

/* Print the current backtrace in a user readable format to a FILE.
   SKIP is the number of frames to skip, as in backtrace_full.  Any
   error messages are printed to stderr.  This function requires debug
   info for the executable.  */

extern void backtrace_print (int skip, FILE *);

/* Given PC, a program counter in the current program, call the
   callback function with filename, line number, and function name
   information.  This will normally call the callback function exactly
   once.  However, if the PC happens to describe an inlined call, and
   the debugging information contains the necessary information, then
   this may call the callback function multiple times.  This will make
   at least one call to either CALLBACK or ERROR_CALLBACK.  This
   returns the first non-zero value returned by CALLBACK, or 0.  */

extern int backtrace_pcinfo (uintptr_t pc, backtrace_full_callback callback,
			     backtrace_error_callback error_callback,
			     void *data);

/* The type of the callback argument to backtrace_syminfo.  DATA and
   PC are the arguments passed to backtrace_syminfo.  SYMNAME is the
   name of the symbol for the corresponding code.  SYMVAL is the
   value.  SYMNAME will be NULL if no error occurred but the symbol
   could not be found.  */

typedef void (*backtrace_syminfo_callback) (void *data, uintptr_t pc,
					    const char *symname,
					    uintptr_t symval);

/* Given PC, a program counter in the current program, call the
   callback information with the symbol name and value describing the
   function in which PC may be found.  This will call either CALLBACK
   or ERROR_CALLBACK exactly once.  This returns 1 on success, 0 on
   failure.  This function requires the symbol table but does not
   require the debug info.  Note that if the symbol table is present
   but PC could not be found in the table, CALLBACK will be called
   with a NULL SYMNAME argument.  Returns 1 on success, 0 on
   error.  */

extern int backtrace_syminfo (uintptr_t pc,
			      backtrace_syminfo_callback callback,
			      backtrace_error_callback error_callback,
			      void *data);

#ifdef __cplusplus
} /* End extern "C".  */
#endif

#endif
Lawrence Crowl Sept. 11, 2012, 11:36 p.m. UTC | #6
On 9/11/12, Ian Lance Taylor <iant@google.com> wrote:
> This patch is the interface to and configury of libbacktrace.
> I've separated these out as the parts of libbacktrace that
> require the most review.  The interface to libbacktrace is in
> the file backtrace.h.  This is what callers will use.  The file
> backtrace-supported.h is also available so that programs can see
> whether calling the backtrace library will work at all.

The interface relies on global data in the library.  Wouldn't it
be better to expose the state as an additional parameter to enable
concurrent access by different threads?  That parameter could then
be modeled as 'this' parameter, addressing Gaby's suggesting.
Ian Lance Taylor Sept. 11, 2012, 11:43 p.m. UTC | #7
On Tue, Sep 11, 2012 at 4:36 PM, Lawrence Crowl <crowl@googlers.com> wrote:
> On 9/11/12, Ian Lance Taylor <iant@google.com> wrote:
>> This patch is the interface to and configury of libbacktrace.
>> I've separated these out as the parts of libbacktrace that
>> require the most review.  The interface to libbacktrace is in
>> the file backtrace.h.  This is what callers will use.  The file
>> backtrace-supported.h is also available so that programs can see
>> whether calling the backtrace library will work at all.
>
> The interface relies on global data in the library.  Wouldn't it
> be better to expose the state as an additional parameter to enable
> concurrent access by different threads?  That parameter could then
> be modeled as 'this' parameter, addressing Gaby's suggesting.

To be clear, the library does support concurrent access by different
threads.  It uses locks internally.  And it would have to use internal
locks even if I adopt your suggestion, because it would not be
reasonable to require each separate thread to independently read and
parse the debug info.

That said, it's a good idea, and I'll see if it makes sense.

Ian
Chris Lattner Sept. 12, 2012, 4:36 a.m. UTC | #8
On Sep 11, 2012, at 4:24 PM, Ian Lance Taylor <iant@google.com> wrote:

> On Tue, Sep 11, 2012 at 4:07 PM, Chris Lattner <clattner@apple.com> wrote:
>> 
>> FYI, "backtrace" is a well-known function provide by glibc (and other libc's).  It might be best to pick another name.
> 
> Good point.  Thanks.  I renamed it to backtrace_full.  I've included
> the updated backtrace.h here.  The other changes are mechanical.

What do you think of (poor man's) namespacification?  You could prefix symbols with "libbacktrace_", which I think is much less likely to conflict, and be much more clear to clients.

-Chris
Ian Lance Taylor Sept. 12, 2012, 4:49 a.m. UTC | #9
On Tue, Sep 11, 2012 at 9:36 PM, Chris Lattner <clattner@apple.com> wrote:
>
> On Sep 11, 2012, at 4:24 PM, Ian Lance Taylor <iant@google.com> wrote:
>
>> On Tue, Sep 11, 2012 at 4:07 PM, Chris Lattner <clattner@apple.com> wrote:
>>>
>>> FYI, "backtrace" is a well-known function provide by glibc (and other libc's).  It might be best to pick another name.
>>
>> Good point.  Thanks.  I renamed it to backtrace_full.  I've included
>> the updated backtrace.h here.  The other changes are mechanical.
>
> What do you think of (poor man's) namespacification?  You could prefix symbols with "libbacktrace_", which I think is much less likely to conflict, and be much more clear to clients.

Right now they all begin with "backtrace_".

Any other opinions on whether "libbacktrace_" is better than "backtrace_"?

Ian
Gabriel Dos Reis Sept. 12, 2012, 4:59 a.m. UTC | #10
On Tue, Sep 11, 2012 at 11:49 PM, Ian Lance Taylor <iant@google.com> wrote:
> On Tue, Sep 11, 2012 at 9:36 PM, Chris Lattner <clattner@apple.com> wrote:
>>
>> On Sep 11, 2012, at 4:24 PM, Ian Lance Taylor <iant@google.com> wrote:
>>
>>> On Tue, Sep 11, 2012 at 4:07 PM, Chris Lattner <clattner@apple.com> wrote:
>>>>
>>>> FYI, "backtrace" is a well-known function provide by glibc (and other libc's).  It might be best to pick another name.
>>>
>>> Good point.  Thanks.  I renamed it to backtrace_full.  I've included
>>> the updated backtrace.h here.  The other changes are mechanical.
>>
>> What do you think of (poor man's) namespacification?  You could prefix symbols with "libbacktrace_", which I think is much less likely to conflict, and be much more clear to clients.
>
> Right now they all begin with "backtrace_".

That is a good choice for a C interface.  I don't think it needs to be longer.

-- Gaby
Ian Lance Taylor Sept. 12, 2012, 2:46 p.m. UTC | #11
On Tue, Sep 11, 2012 at 4:36 PM, Lawrence Crowl <crowl@googlers.com> wrote:
> On 9/11/12, Ian Lance Taylor <iant@google.com> wrote:
>> This patch is the interface to and configury of libbacktrace.
>> I've separated these out as the parts of libbacktrace that
>> require the most review.  The interface to libbacktrace is in
>> the file backtrace.h.  This is what callers will use.  The file
>> backtrace-supported.h is also available so that programs can see
>> whether calling the backtrace library will work at all.
>
> The interface relies on global data in the library.  Wouldn't it
> be better to expose the state as an additional parameter to enable
> concurrent access by different threads?  That parameter could then
> be modeled as 'this' parameter, addressing Gaby's suggesting.

I went ahead and added a state parameter to the interface.  I've
attached the updated patch.

Ian
Joseph Myers Sept. 12, 2012, 4:23 p.m. UTC | #12
On Tue, 11 Sep 2012, Ian Lance Taylor wrote:

> The configury is fairly standard.  Note that libbacktrace is built as
> both a host library (to link into the compilers) and as a target library
> (to link into libgo and possibly other libraries).

Under what circumstances will the library be built for the target - only 
if a relevant language such as Go is being built, or unconditionally?

If built unconditionally, will the library build OK for the target in 
situations where no target headers are yet available?  (For such builds of 
compilers used to bootstrap libc it would be usual to use various 
--disable- options to disable libraries not needed to build libc, and to 
use --enable-languages=c, but if this library is used on the host side by 
the compiler then the generic --disable-libbacktrace might not suffice 
since that would disable the host copy, required by the compiler itself, 
as well as the target copy.)
Toon Moene Sept. 12, 2012, 4:25 p.m. UTC | #13
On 09/12/2012 01:08 AM, Ian Lance Taylor wrote:

> The interface is somewhat constrained in that, on systems that support
> anonymous mmap, it does not call malloc.  That makes it possible to do
> a symbolic backtrace from a signal handler.

It would also make it possible to have a traceback of a segmentation 
fault caused by corruption of the malloc arena ...
Lawrence Crowl Sept. 12, 2012, 5:31 p.m. UTC | #14
On 9/12/12, Ian Lance Taylor <iant@google.com> wrote:
> On Sep 11, 2012 Lawrence Crowl <crowl@googlers.com> wrote:
> > On 9/11/12, Ian Lance Taylor <iant@google.com> wrote:
> > > This patch is the interface to and configury of libbacktrace.
> > > I've separated these out as the parts of libbacktrace that
> > > require the most review.  The interface to libbacktrace is in
> > > the file backtrace.h.  This is what callers will use.  The file
> > > backtrace-supported.h is also available so that programs can
> > > see whether calling the backtrace library will work at all.
> >
> > The interface relies on global data in the library.  Wouldn't it
> > be better to expose the state as an additional parameter to
> > enable concurrent access by different threads?  That parameter
> > could then be modeled as 'this' parameter, addressing Gaby's
> > suggesting.
>
> I went ahead and added a state parameter to the interface.
> I've attached the updated patch.

How about typing it as a pointer to an incomplete struct?

extern void *backtrace_create_state (...

becomes, e.g.,

struct backtrace_state;
extern backtrace_state *backtrace_create_state (...
Ian Lance Taylor Sept. 12, 2012, 6:59 p.m. UTC | #15
On Wed, Sep 12, 2012 at 9:23 AM, Joseph S. Myers
<joseph@codesourcery.com> wrote:
> On Tue, 11 Sep 2012, Ian Lance Taylor wrote:
>
>> The configury is fairly standard.  Note that libbacktrace is built as
>> both a host library (to link into the compilers) and as a target library
>> (to link into libgo and possibly other libraries).
>
> Under what circumstances will the library be built for the target - only
> if a relevant language such as Go is being built, or unconditionally?

My intent is to only build it when something needs it, e.g., libgo.  I
don't know if I've expressed that intent correctly.

> If built unconditionally, will the library build OK for the target in
> situations where no target headers are yet available?  (For such builds of
> compilers used to bootstrap libc it would be usual to use various
> --disable- options to disable libraries not needed to build libc, and to
> use --enable-languages=c, but if this library is used on the host side by
> the compiler then the generic --disable-libbacktrace might not suffice
> since that would disable the host copy, required by the compiler itself,
> as well as the target copy.)

The library does currently assume that a few header files are
available, so building it would presumably break in this scenario.  We
could introduce --disable-target-libbacktrace easily enough.

Ian
Ian Lance Taylor Sept. 12, 2012, 7:04 p.m. UTC | #16
On Wed, Sep 12, 2012 at 10:31 AM, Lawrence Crowl <crowl@googlers.com> wrote:
>
> How about typing it as a pointer to an incomplete struct?
>
> extern void *backtrace_create_state (...
>
> becomes, e.g.,
>
> struct backtrace_state;
> extern backtrace_state *backtrace_create_state (...

Yeah, that is probably the way to do it.  I made that change.  I won't
bother to send around the patches again.

Ian
Joseph Myers Sept. 12, 2012, 9:04 p.m. UTC | #17
On Wed, 12 Sep 2012, Ian Lance Taylor wrote:

> On Wed, Sep 12, 2012 at 9:23 AM, Joseph S. Myers
> <joseph@codesourcery.com> wrote:
> > On Tue, 11 Sep 2012, Ian Lance Taylor wrote:
> >
> >> The configury is fairly standard.  Note that libbacktrace is built as
> >> both a host library (to link into the compilers) and as a target library
> >> (to link into libgo and possibly other libraries).
> >
> > Under what circumstances will the library be built for the target - only
> > if a relevant language such as Go is being built, or unconditionally?
> 
> My intent is to only build it when something needs it, e.g., libgo.  I
> don't know if I've expressed that intent correctly.

I think that if a library is listed in target_libs in config-lang.in for 
at least one language, and if all languages with it so listed are 
disabled, then that library will be disabled - but if no languages list it 
in config-lang.in, it will be enabled by default.
Diego Novillo Sept. 13, 2012, 8 p.m. UTC | #18
On 2012-09-11 18:53 , Ian Lance Taylor wrote:

> 2012-09-11  Ian Lance Taylor  <iant@google.com>
>
> 	* Initial implementation.

OK.


Diego.
Ian Lance Taylor Sept. 17, 2012, 4:39 p.m. UTC | #19
On Thu, Sep 13, 2012 at 1:00 PM, Diego Novillo <dnovillo@google.com> wrote:
> On 2012-09-11 18:53 , Ian Lance Taylor wrote:
>
>> 2012-09-11  Ian Lance Taylor  <iant@google.com>
>>
>>         * Initial implementation.
>
> OK.

Thanks for all the reviews.  I have committed the libbacktrace library
to trunk.  I will follow up with a patch to actually use it.

Please let me know about any build problems.

Ian
Ryan Mansfield Sept. 19, 2012, 8:56 p.m. UTC | #20
On 12-09-17 12:39 PM, Ian Lance Taylor wrote:
> On Thu, Sep 13, 2012 at 1:00 PM, Diego Novillo <dnovillo@google.com> wrote:
>> On 2012-09-11 18:53 , Ian Lance Taylor wrote:
>>
>>> 2012-09-11  Ian Lance Taylor  <iant@google.com>
>>>
>>>          * Initial implementation.
>>
>> OK.
>
> Thanks for all the reviews.  I have committed the libbacktrace library
> to trunk.  I will follow up with a patch to actually use it.
>
> Please let me know about any build problems.

I'm hitting the following build issue

/bin/sh ./libtool --tag=CC   --mode=compile i686-unknown-linux-gnu-gcc 
-DHAVE_CONFIG_H -I. -I../../libbacktrace  -I 
../../libbacktrace/../include -I ../../libbacktrace/../libgcc -I 
../libgcc -I ../gcc/include -I ../../gcc/include  -W -Wall 
-Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes 
-Wold-style-definition -Wmissing-format-attribute -Wcast-qual -Werror 
-g -O2 -MT backtrace.lo -MD -MP -MF .deps/backtrace.Tpo -c -o 
backtrace.lo ../../libbacktrace/backtrace.c
libtool: compile:  i686-unknown-linux-gnu-gcc -DHAVE_CONFIG_H -I. 
-I../../libbacktrace -I ../../libbacktrace/../include -I 
../../libbacktrace/../libgcc -I ../libgcc -I ../gcc/include -I 
../../gcc/include -W -Wall -Wwrite-strings -Wstrict-prototypes 
-Wmissing-prototypes -Wold-style-definition -Wmissing-format-attribute 
-Wcast-qual -Werror -g -O2 -MT backtrace.lo -MD -MP -MF 
.deps/backtrace.Tpo -c ../../libbacktrace/backtrace.c -o backtrace.o
cc1: warnings being treated as errors
../../libbacktrace/backtrace.c: In function 'unwind':
../../libbacktrace/backtrace.c:69: warning: implicit declaration of 
function '_Unwind_GetIPInfo'
make[3]: *** [backtrace.lo] Error 1

Regards,

Ryan Mansfield
Ian Lance Taylor Sept. 19, 2012, 10:17 p.m. UTC | #21
On Wed, Sep 19, 2012 at 1:56 PM, Ryan Mansfield <rmansfield@qnx.com> wrote:
>
> I'm hitting the following build issue
>
> /bin/sh ./libtool --tag=CC   --mode=compile i686-unknown-linux-gnu-gcc
> -DHAVE_CONFIG_H -I. -I../../libbacktrace  -I ../../libbacktrace/../include
> -I ../../libbacktrace/../libgcc -I ../libgcc -I ../gcc/include -I
> ../../gcc/include  -W -Wall -Wwrite-strings -Wstrict-prototypes
> -Wmissing-prototypes -Wold-style-definition -Wmissing-format-attribute
> -Wcast-qual -Werror -g -O2 -MT backtrace.lo -MD -MP -MF .deps/backtrace.Tpo
> -c -o backtrace.lo ../../libbacktrace/backtrace.c
> libtool: compile:  i686-unknown-linux-gnu-gcc -DHAVE_CONFIG_H -I.
> -I../../libbacktrace -I ../../libbacktrace/../include -I
> ../../libbacktrace/../libgcc -I ../libgcc -I ../gcc/include -I
> ../../gcc/include -W -Wall -Wwrite-strings -Wstrict-prototypes
> -Wmissing-prototypes -Wold-style-definition -Wmissing-format-attribute
> -Wcast-qual -Werror -g -O2 -MT backtrace.lo -MD -MP -MF .deps/backtrace.Tpo
> -c ../../libbacktrace/backtrace.c -o backtrace.o
>
> cc1: warnings being treated as errors
> ../../libbacktrace/backtrace.c: In function 'unwind':
> ../../libbacktrace/backtrace.c:69: warning: implicit declaration of function
> '_Unwind_GetIPInfo'
> make[3]: *** [backtrace.lo] Error 1

Don't omit the details: How precisely did you run configure?  In what
directory is this error occurring?

Please check HAVE_GETIPINFO in libbacktrace/config.h.  I assume it is 1.

It looks like you may be doing some sort of Canadian Cross build.
What version of GCC is i686-unknown-linux-gnu-gcc?  Does that version
of gcc declare _Unwind_GetIPInfo in its unwind.h?  Does it provide
_Unwind_GetIPInfo in its libgcc?

Ian
Ryan Mansfield Sept. 19, 2012, 10:31 p.m. UTC | #22
On 12-09-19 06:17 PM, Ian Lance Taylor wrote:
> On Wed, Sep 19, 2012 at 1:56 PM, Ryan Mansfield <rmansfield@qnx.com> wrote:
>>
>> I'm hitting the following build issue
>>
>> /bin/sh ./libtool --tag=CC   --mode=compile i686-unknown-linux-gnu-gcc
>> -DHAVE_CONFIG_H -I. -I../../libbacktrace  -I ../../libbacktrace/../include
>> -I ../../libbacktrace/../libgcc -I ../libgcc -I ../gcc/include -I
>> ../../gcc/include  -W -Wall -Wwrite-strings -Wstrict-prototypes
>> -Wmissing-prototypes -Wold-style-definition -Wmissing-format-attribute
>> -Wcast-qual -Werror -g -O2 -MT backtrace.lo -MD -MP -MF .deps/backtrace.Tpo
>> -c -o backtrace.lo ../../libbacktrace/backtrace.c
>> libtool: compile:  i686-unknown-linux-gnu-gcc -DHAVE_CONFIG_H -I.
>> -I../../libbacktrace -I ../../libbacktrace/../include -I
>> ../../libbacktrace/../libgcc -I ../libgcc -I ../gcc/include -I
>> ../../gcc/include -W -Wall -Wwrite-strings -Wstrict-prototypes
>> -Wmissing-prototypes -Wold-style-definition -Wmissing-format-attribute
>> -Wcast-qual -Werror -g -O2 -MT backtrace.lo -MD -MP -MF .deps/backtrace.Tpo
>> -c ../../libbacktrace/backtrace.c -o backtrace.o
>>
>> cc1: warnings being treated as errors
>> ../../libbacktrace/backtrace.c: In function 'unwind':
>> ../../libbacktrace/backtrace.c:69: warning: implicit declaration of function
>> '_Unwind_GetIPInfo'
>> make[3]: *** [backtrace.lo] Error 1
>
> Don't omit the details: How precisely did you run configure?  In what
> directory is this error occurring?

$ head config.log
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.

It was created by configure, which was
generated by GNU Autoconf 2.64.  Invocation command line was

   $ ../configure --disable-bootstrap --enable-languages=c++

## --------- ##
## Platform. ##


> Please check HAVE_GETIPINFO in libbacktrace/config.h.  I assume it is 1.

Yep, it's 1.

$ grep  HAVE_GETIPINFO config.h
#define HAVE_GETIPINFO 1

> It looks like you may be doing some sort of Canadian Cross build.
> What version of GCC is i686-unknown-linux-gnu-gcc?  Does that version
> of gcc declare _Unwind_GetIPInfo in its unwind.h?  Does it provide
> _Unwind_GetIPInfo in its libgcc?

I'm using gcc 4.1 on this machine. No, it doesn't have it in the 
unwind.h or libgcc.

Regards,

Ryan Mansfield
Ian Lance Taylor Sept. 19, 2012, 10:58 p.m. UTC | #23
On Wed, Sep 19, 2012 at 3:31 PM, Ryan Mansfield <rmansfield@qnx.com> wrote:

> $ head config.log
> This file contains any messages produced by compilers while
> running configure, to aid debugging if configure makes a mistake.
>
> It was created by configure, which was
> generated by GNU Autoconf 2.64.  Invocation command line was
>
>   $ ../configure --disable-bootstrap --enable-languages=c++
>
> ## --------- ##
> ## Platform. ##
>
>
>
>> Please check HAVE_GETIPINFO in libbacktrace/config.h.  I assume it is 1.
>
>
> Yep, it's 1.
>
> $ grep  HAVE_GETIPINFO config.h
> #define HAVE_GETIPINFO 1
>
>
>> It looks like you may be doing some sort of Canadian Cross build.
>> What version of GCC is i686-unknown-linux-gnu-gcc?  Does that version
>> of gcc declare _Unwind_GetIPInfo in its unwind.h?  Does it provide
>> _Unwind_GetIPInfo in its libgcc?
>
>
> I'm using gcc 4.1 on this machine. No, it doesn't have it in the unwind.h or
> libgcc.

Thanks for the additional info.  I have committed this patch, which
should fix the problem.  Bootstrapped and ran libbacktrace tests on
x86_64-unknown-linux-gnu.

Ian

2012-09-19  Ian Lance Taylor  <iant@google.com>

	* configure.ac: Only use GCC_CHECK_UNWIND_GETIPINFO when compiled
	as a target library.
	* configure: Rebuild.
Ryan Mansfield Sept. 20, 2012, 12:29 a.m. UTC | #24
On 12-09-19 06:58 PM, Ian Lance Taylor wrote:
> Thanks for the additional info.  I have committed this patch, which
> should fix the problem.  Bootstrapped and ran libbacktrace tests on
> x86_64-unknown-linux-gnu.

Thanks Ian. This patch fixes the issue.

Regards,

Ryan Mansfield

> 2012-09-19  Ian Lance Taylor  <iant@google.com>
>
> 	* configure.ac: Only use GCC_CHECK_UNWIND_GETIPINFO when compiled
> 	as a target library.
> 	* configure: Rebuild.
>
diff mbox

Patch

Index: libbacktrace/README
===================================================================
--- libbacktrace/README	(revision 0)
+++ libbacktrace/README	(revision 0)
@@ -0,0 +1,23 @@ 
+The libbacktrace library
+Initially written by Ian Lance Taylor <iant@google.com>
+
+The libbacktrace library may be linked into a program or library and
+used to produce symbolic backtraces.  Sample uses would be to print a
+detailed backtrace when an error occurs or to gather detailed
+profiling information.
+
+The libbacktrace library is provided under a BSD license.  See the
+source files for the exact license text.
+
+The public functions are declared and documented in the header file
+backtrace.h, which should be #include'd by a user of the library.
+
+Building libbacktrace will generate a file backtrace-supported.h,
+which a user of the library may use to determine whether backtraces
+will work.  See the source file backtrace-supported.h.in for the
+macros that it defines.
+
+As of September 2012, libbacktrace only supports ELF executables with
+DWARF debugging information.  The library is written to make it
+straightforward to add support for other object file and debugging
+formats.
Index: libbacktrace/backtrace.h
===================================================================
--- libbacktrace/backtrace.h	(revision 0)
+++ libbacktrace/backtrace.h	(revision 0)
@@ -0,0 +1,165 @@ 
+/* backtrace.h -- Public header file for stack backtrace library.
+   Copyright (C) 2012 Free Software Foundation, Inc.
+   Written by Ian Lance Taylor, Google.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    (1) Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer. 
+
+    (2) Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in
+    the documentation and/or other materials provided with the
+    distribution.  
+    
+    (3) The name of the author may not be used to
+    endorse or promote products derived from this software without
+    specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.  */
+
+#ifndef BACKTRACE_H
+#define BACKTRACE_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The backtrace code needs to open the executable file in order to
+   find the debug info.  On systems that do not support
+   /proc/self/exe, the program using the backtrace library needs to
+   tell the backtrace library the name of the executable to open.  It
+   does so by calling backtrace_set_executable_name.  The FILENAME
+   argument must point to a permanent buffer.  */
+
+extern void backtrace_set_executable_name (const char *filename);
+
+/* The type of the callback argument to the backtrace function.  DATA
+   is the argument passed to backtrace.  PC is the program counter.
+   FILENAME is the name of the file containing PC, or NULL if not
+   available.  LINENO is the line number in FILENAME containing PC, or
+   0 if not available.  FUNCTION is the name of the function
+   containing PC, or NULL if not available.  This should return 0 to
+   continuing tracing.  The FILENAME and FUNCTION buffers may become
+   invalid after this function returns.  */
+
+typedef int (*backtrace_callback) (void *data, uintptr_t pc,
+				   const char *filename, int lineno,
+				   const char *function);
+
+/* The type of the error callback argument to backtrace functions.
+   This function, if not NULL, will be called for certain error cases.
+   The DATA argument is passed to the function that calls this one.
+   The MSG argument is an error message.  The ERRNUM argument, if
+   greater than 0, holds an errno value.  The MSG buffer may become
+   invalid after this function returns.
+
+   As a special case, the ERRNUM argument will be passed as -1 if no
+   debug info can be found for the executable, but the function
+   requires debug info (e.g., backtrace, backtrace_pcinfo).  The MSG
+   in this case will be something along the lines of "no debug info".
+   Similarly, ERRNUM will be passed as -1 if there is no symbol table,
+   but the function requires a symbol table (e.g., backtrace_syminfo).
+   This may be used as a signal that some other approach should be
+   tried.  */
+
+typedef void (*backtrace_error_callback) (void *data, const char *msg,
+					  int errnum);
+
+/* Get a full stack backtrace.  SKIP is the number of frames to skip;
+   passing 0 will start the trace with the function calling backtrace.
+   DATA is passed to the callback routine.  If any call to CALLBACK
+   returns a non-zero value, the stack backtrace stops, and backtrace
+   returns that value; this may be used to limit the number of stack
+   frames desired.  If all calls to CALLBACK return 0, backtrace
+   returns 0.  The backtrace function will make at least one call to
+   either CALLBACK or ERROR_CALLBACK.  This function requires debug
+   info for the executable.  */
+
+extern int backtrace (int skip, backtrace_callback callback,
+		      backtrace_error_callback error_callback, void *data);
+
+/* The type of the callback argument to the simple backtrace function.
+   DATA is the argument passed to simple_backtrace.  PC is the program
+   counter.  This should return 0 to continue tracing.  */
+
+typedef int (*backtrace_simple_callback) (void *data, uintptr_t pc);
+
+/* Get a simple backtrace.  SKIP is the number of frames to skip, as
+   in backtrace.  DATA is passed to the callback routine.  If any call
+   to CALLBACK returns a non-zero value, the stack backtrace stops,
+   and simple_backtrace returns that value.  Otherwise
+   simple_backtrace returns 0.  The backtrace_simple function will
+   make at least one call to either CALLBACK or ERROR_CALLBACK.  This
+   function does not require any debug info for the executable.  */
+
+extern int backtrace_simple (int skip, backtrace_simple_callback callback,
+			     backtrace_error_callback error_callback,
+			     void *data);
+
+/* Print the current backtrace in a user readable format to a FILE.
+   SKIP is the number of frames to skip, as in backtrace.  Any error
+   messages are printed to stderr.  This function requires debug info
+   for the executable.  */
+
+extern void backtrace_print (int skip, FILE *);
+
+/* Given PC, a program counter in the current program, call the
+   callback function with filename, line number, and function name
+   information.  This will normally call the callback function exactly
+   once.  However, if the PC happens to describe an inlined call, and
+   the debugging information contains the necessary information, then
+   this may call the callback function multiple times.  This will make
+   at least one call to either CALLBACK or ERROR_CALLBACK.  This
+   returns the first non-zero value returned by CALLBACK, or 0.  */
+
+extern int backtrace_pcinfo (uintptr_t pc, backtrace_callback callback,
+			     backtrace_error_callback error_callback,
+			     void *data);
+
+/* The type of the callback argument to backtrace_syminfo.  DATA and
+   PC are the arguments passed to backtrace_syminfo.  SYMNAME is the
+   name of the symbol for the corresponding code.  SYMVAL is the
+   value.  SYMNAME will be NULL if no error occurred but the symbol
+   could not be found.  */
+
+typedef void (*backtrace_syminfo_callback) (void *data, uintptr_t pc,
+					    const char *symname,
+					    uintptr_t symval);
+
+/* Given PC, a program counter in the current program, call the
+   callback information with the symbol name and value describing the
+   function in which PC may be found.  This will call either CALLBACK
+   or ERROR_CALLBACK exactly once.  This returns 1 on success, 0 on
+   failure.  This function requires the symbol table but does not
+   require the debug info.  Note that if the symbol table is present
+   but PC could not be found in the table, CALLBACK will be called
+   with a NULL SYMNAME argument.  Returns 1 on success, 0 on
+   error.  */
+
+extern int backtrace_syminfo (uintptr_t pc,
+			      backtrace_syminfo_callback callback,
+			      backtrace_error_callback error_callback,
+			      void *data);
+
+#ifdef __cplusplus
+} /* End extern "C".  */
+#endif
+
+#endif
Index: libbacktrace/configure.ac
===================================================================
--- libbacktrace/configure.ac	(revision 0)
+++ libbacktrace/configure.ac	(revision 0)
@@ -0,0 +1,256 @@ 
+# configure.ac -- Backtrace configure script.
+# Copyright (C) 2012 Free Software Foundation, Inc.
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+
+#     (1) Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+
+#     (2) Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in
+#     the documentation and/or other materials provided with the
+#     distribution.  
+    
+#     (3) The name of the author may not be used to
+#     endorse or promote products derived from this software without
+#     specific prior written permission.
+
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+AC_PREREQ(2.64)
+AC_INIT(package-unused, version-unused,, libbacktrace)
+AC_CONFIG_SRCDIR(backtrace.h)
+AC_CONFIG_HEADER(config.h)
+
+AC_CANONICAL_SYSTEM
+target_alias=${target_alias-$host_alias}
+
+libtool_VERSION=1:0:0
+AC_SUBST(libtool_VERSION)
+
+AM_INIT_AUTOMAKE([1.11.1 foreign no-dist no-define -Wall -Wno-portability])
+
+AM_MAINTAINER_MODE
+
+AC_ARG_WITH(target-subdir,
+[  --with-target-subdir=SUBDIR      Configuring in a subdirectory for target])
+
+# We must force CC to /not/ be precious variables; otherwise
+# the wrong, non-multilib-adjusted value will be used in multilibs.
+# As a side effect, we have to subst CFLAGS ourselves.
+m4_rename([_AC_ARG_VAR_PRECIOUS],[backtrace_PRECIOUS])
+m4_define([_AC_ARG_VAR_PRECIOUS],[])
+AC_PROG_CC
+m4_rename_force([backtrace_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
+
+AC_SUBST(CFLAGS)
+
+AC_PROG_RANLIB
+
+AC_PROG_AWK
+case "$AWK" in
+"") AC_MSG_ERROR([can't build without awk]) ;;
+esac
+
+LT_INIT([disable-shared])
+AM_PROG_LIBTOOL
+
+backtrace_supported=yes
+
+if test -n "${with_target_subdir}"; then
+  # We are compiling a GCC library.  We can assume that the unwind
+  # library exists.
+  AM_ENABLE_MULTILIB(, ..)
+  BACKTRACE_FILE="backtrace.lo simple.lo"
+else
+  AC_CHECK_HEADER([unwind.h],
+    [AC_CHECK_FUNC([_Unwind_Backtrace],
+	           [BACKTRACE_FILE="backtrace.lo simple.lo"],
+		   [BACKTRACE_FILE="nounwind.lo"
+                    backtrace_supported=no])],
+    [BACKTRACE_FILE="nounwind.lo"
+     backtrace_supported=no])
+fi
+AC_SUBST(BACKTRACE_FILE)
+
+AC_ARG_ENABLE([backtrace-threads],
+  AC_HELP_STRING([--enable-backtrace-threads],
+		 [Specify that the backtrace library will be used by threaded programs]),
+  [case "$enableval" in
+   yes) backtrace_threads=yes ;;
+   no) backtrace_threads=no ;;
+   *) AC_MSG_ERROR([Unknown argument to --enable-backtrace-threads/--disable-backtrace-threads]) ;;
+   esac],
+   [if test -n "${with_target_subdir}"; then
+      backtrace_threads=yes
+    else
+      backtrace_threads=no
+    fi])
+
+ACX_PROG_CC_WARNING_OPTS([-W -Wall -Wwrite-strings -Wstrict-prototypes \
+			  -Wmissing-prototypes -Wold-style-definition \
+			  -Wmissing-format-attribute -Wcast-qual],
+			  [WARN_FLAGS])
+
+if test "x$GCC" = "xyes"; then
+  WARN_FLAGS="$WARN_FLAGS -Werror"
+fi
+
+AC_SUBST(WARN_FLAGS)
+
+GCC_CHECK_UNWIND_GETIPINFO
+
+# When building as a target library, shared libraries may want to link
+# this in.  We don't want to provide another shared library to
+# complicate dependencies.  Instead, we just compile with -fPIC.
+PIC_FLAG=
+if test -n "${with_target_subdir}"; then
+  PIC_FLAG=-fPIC
+fi
+AC_SUBST(PIC_FLAG)
+
+# The library needs to be able to read the executable itself.  Compile
+# a file to determine the executable format.  The awk script
+# filetype.awk prints out the file type.
+AC_CACHE_CHECK([output filetype],
+[libbacktrace_cv_sys_filetype],
+[filetype=
+AC_COMPILE_IFELSE(
+  [AC_LANG_PROGRAM([int i;], [int j;])],
+  [filetype=`${AWK} -f $srcdir/filetype.awk conftest.$ac_objext`],
+  [AC_MSG_FAILURE([compiler failed])])
+libbacktrace_cv_sys_filetype=$filetype])
+
+# Match the file type to decide what files to compile.
+FORMAT_FILE=
+case "$libbacktrace_cv_sys_filetype" in
+elf*) FORMAT_FILE="elf.lo" ;;
+*) AC_MSG_WARN([could not determine output file type])
+   FORMAT_FILE="unknown.lo"
+   backtrace_supported=no
+   ;;
+esac
+AC_SUBST(FORMAT_FILE)
+
+# ELF defines.
+elfsize=
+case "$libbacktrace_cv_sys_filetype" in
+elf32) elfsize=32 ;;
+elf64) elfsize=64 ;;
+esac
+AC_DEFINE_UNQUOTED([BACKTRACE_ELF_SIZE], [$elfsize], [ELF size: 32 or 64])
+
+BACKTRACE_SUPPORTED=0
+if test "$backtrace_supported" = "yes"; then
+  BACKTRACE_SUPPORTED=1
+fi
+AC_SUBST(BACKTRACE_SUPPORTED)
+
+if test "$backtrace_threads" = "yes"; then
+  if test -n "${with_target_subdir}"; then
+    THREAD_FILE=gthread.lo
+  else
+    THREAD_FILE=thread.lo
+  fi
+else
+  THREAD_FILE=nothread.lo
+fi
+AC_SUBST(THREAD_FILE)
+
+AC_CHECK_HEADERS(sys/mman.h)
+if test "$ac_cv_header_sys_mman_h" = "no"; then
+  have_mmap=no
+else
+  if test -n "${with_target_subdir}"; then
+    # When built as a GCC target library, we can't do a link test.  We
+    # simply assume that if we have mman.h, we have mmap.
+    have_mmap=yes
+  else
+    AC_CHECK_FUNC(mmap, [have_mmap=yes], [have_mmap=no])
+  fi
+fi
+if test "$have_mmap" = "no"; then
+  VIEW_FILE=read.lo
+  ALLOC_FILE=alloc.lo
+else
+  VIEW_FILE=mmapio.lo
+  AC_PREPROC_IFELSE([
+#include <sys/mman.h>
+#if !defined(MAP_ANONYMOUS) && !defined(MAP_ANON)
+  #error no MAP_ANONYMOUS
+#endif
+], [ALLOC_FILE=mmap.lo], [ALLOC_FILE=alloc.lo])
+fi
+AC_SUBST(VIEW_FILE)
+AC_SUBST(ALLOC_FILE)
+
+BACKTRACE_USES_MALLOC=0
+if test "$ALLOC_FILE" = "alloc.lo"; then
+  BACKTRACE_USES_MALLOC=1
+fi
+AC_SUBST(BACKTRACE_USES_MALLOC)
+
+AC_CACHE_CHECK([whether tests can run],
+  [libbacktrace_cv_sys_native],
+  [AC_RUN_IFELSE([AC_LANG_PROGRAM([], [return 0;])],
+     [libbacktrace_cv_sys_native=yes],
+     [libbacktrace_cv_sys_native=no],
+     [libbacktrace_cv_sys_native=no])])
+AM_CONDITIONAL(NATIVE, test "$libbacktrace_cv_sys_native" = "yes")
+
+if test "${multilib}" = "yes"; then
+  multilib_arg="--enable-multilib"
+else
+  multilib_arg=
+fi
+
+AC_CONFIG_FILES(Makefile backtrace-supported.h)
+
+# We need multilib support, but only if configuring for the target.
+AC_CONFIG_COMMANDS([default],
+[if test -n "$CONFIG_FILES"; then
+   if test -n "${with_target_subdir}"; then
+     # Multilibs need MULTISUBDIR defined correctly in certain makefiles so
+     # that multilib installs will end up installed in the correct place.
+     # The testsuite needs it for multilib-aware ABI baseline files.
+     # To work around this not being passed down from config-ml.in ->
+     # srcdir/Makefile.am -> srcdir/{src,libsupc++,...}/Makefile.am, manually
+     # append it here.  Only modify Makefiles that have just been created.
+     #
+     # Also, get rid of this simulated-VPATH thing that automake does.
+     cat > vpsed << \_EOF
+  s!`test -f '$<' || echo '$(srcdir)/'`!!
+_EOF
+     for i in $SUBDIRS; do
+      case $CONFIG_FILES in
+       *${i}/Makefile*)
+	 #echo "Adding MULTISUBDIR to $i/Makefile"
+	 sed -f vpsed $i/Makefile > tmp
+	 grep '^MULTISUBDIR =' Makefile >> tmp
+	 mv tmp $i/Makefile
+	 ;;
+      esac
+     done
+     rm vpsed
+   fi
+ fi
+],
+[
+# Variables needed in config.status (file generation) which aren't already
+# passed by autoconf.
+SUBDIRS="$SUBDIRS"
+])
+
+AC_OUTPUT
Index: libbacktrace/backtrace-supported.h.in
===================================================================
--- libbacktrace/backtrace-supported.h.in	(revision 0)
+++ libbacktrace/backtrace-supported.h.in	(revision 0)
@@ -0,0 +1,54 @@ 
+/* backtrace-supported.h.in -- Whether stack backtrace is supported.
+   Copyright (C) 2012 Free Software Foundation, Inc.
+   Written by Ian Lance Taylor, Google.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    (1) Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer. 
+
+    (2) Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in
+    the documentation and/or other materials provided with the
+    distribution.  
+    
+    (3) The name of the author may not be used to
+    endorse or promote products derived from this software without
+    specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.  */
+
+/* The file backtrace-supported.h.in is used by configure to generate
+   the file backtrace-supported.h.  The file backtrace-supported.h may
+   be #include'd to see whether the backtrace library will be able to
+   get a backtrace and produce symbolic information.  */
+
+
+/* BACKTRACE_SUPPORTED will be #define'd as 1 if the backtrace library
+   should work, 0 if it will not.  Libraries may #include this to make
+   other arrangements.  */
+
+#define BACKTRACE_SUPPORTED @BACKTRACE_SUPPORTED@
+
+/* BACKTRACE_USES_MALLOC will be #define'd as 1 if the backtrace
+   library will call malloc as it works, 0 if it will call mmap
+   instead.  This may be used to determine whether it is safe to call
+   the backtrace functions from a signal handler.  In general this
+   only applies to calls like backtrace and backtrace_pcinfo.  It does
+   not apply to backtrace_simple, which never calls malloc.  It does
+   not apply to backtrace_print, which always calls fprintf and
+   therefore malloc.  */
+
+#define BACKTRACE_USES_MALLOC @BACKTRACE_USES_MALLOC@
Index: libbacktrace/filetype.awk
===================================================================
--- libbacktrace/filetype.awk	(revision 0)
+++ libbacktrace/filetype.awk	(revision 0)
@@ -0,0 +1,3 @@ 
+# An awk script to determine the type of a file.
+/\177ELF\001/ { if (NR == 1) { print "elf32"; exit } }
+/\177ELF\002/ { if (NR == 1) { print "elf64"; exit } }
Index: libbacktrace/Makefile.am
===================================================================
--- libbacktrace/Makefile.am	(revision 0)
+++ libbacktrace/Makefile.am	(revision 0)
@@ -0,0 +1,98 @@ 
+# Makefile.am -- Backtrace Makefile.
+# Copyright (C) 2012 Free Software Foundation, Inc.
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+
+#     (1) Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+
+#     (2) Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in
+#     the documentation and/or other materials provided with the
+#     distribution.  
+    
+#     (3) The name of the author may not be used to
+#     endorse or promote products derived from this software without
+#     specific prior written permission.
+
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+ACLOCAL_AMFLAGS = -I .. -I ../config
+
+AM_CFLAGS = $(WARN_FLAGS) $(PIC_FLAG) -I $(srcdir)/../include -I ../libgcc
+
+noinst_LTLIBRARIES = libbacktrace.la
+
+libbacktrace_la_SOURCES = \
+	backtrace.h \
+	dwarf.c \
+	fileline.c \
+	internal.h \
+	posix.c \
+	print.c
+
+BACKTRACE_FILES = \
+	backtrace.c \
+	simple.c \
+	nounwind.c
+
+FORMAT_FILES = \
+	elf.c \
+	unknown.c
+
+THREAD_FILES = \
+	thread.c \
+	gthread.c \
+	nothread.c
+
+VIEW_FILES = \
+	read.c \
+	mmapio.c
+
+ALLOC_FILES = \
+	alloc.c \
+	mmap.c
+
+EXTRA_libbacktrace_la_SOURCES = \
+	$(BACKTRACE_FILES) \
+	$(FORMAT_FILES) \
+	$(THREAD_FILES) \
+	$(VIEW_FILES) \
+	$(ALLOC_FILES)
+
+libbacktrace_la_LIBADD = \
+	$(BACKTRACE_FILE) \
+	$(FORMAT_FILE) \
+	$(THREAD_FILE) \
+	$(VIEW_FILE) \
+	$(ALLOC_FILE)
+
+libbacktrace_la_DEPENDENCIES = $(libbacktrace_la_LIBADD)
+
+# Testsuite.
+
+check_PROGRAMS =
+
+TESTS = $(check_PROGRAMS)
+
+if NATIVE
+
+btest_SOURCES = btest.c
+btest_CFLAGS = $(AM_CFLAGS) -g -O
+btest_LDADD = libbacktrace.la
+
+check_PROGRAMS += btest
+
+endif NATIVE