re PR other/67457 (segfault in libbacktrace)
PR other/67457 * backtrace.c: #include "internal.h". (struct backtrace_data): Add can_alloc field. (unwind): If can_alloc is false, don't try to get file/line information. (backtrace_full): Set can_alloc field in bdata. * alloc.c (backtrace_alloc): Don't call error_callback if it is NULL. * mmap.c (backtrace_alloc): Likewise. * internal.h: Update comments for backtrace_alloc and backtrace_free. From-SVN: r227533
This commit is contained in:
parent
2eab96661b
commit
c478516be7
5 changed files with 51 additions and 8 deletions
|
@ -1,3 +1,17 @@
|
||||||
|
2015-09-08 Ian Lance Taylor <iant@google.com>
|
||||||
|
|
||||||
|
PR other/67457
|
||||||
|
* backtrace.c: #include "internal.h".
|
||||||
|
(struct backtrace_data): Add can_alloc field.
|
||||||
|
(unwind): If can_alloc is false, don't try to get file/line
|
||||||
|
information.
|
||||||
|
(backtrace_full): Set can_alloc field in bdata.
|
||||||
|
* alloc.c (backtrace_alloc): Don't call error_callback if it is
|
||||||
|
NULL.
|
||||||
|
* mmap.c (backtrace_alloc): Likewise.
|
||||||
|
* internal.h: Update comments for backtrace_alloc and
|
||||||
|
backtrace_free.
|
||||||
|
|
||||||
2015-09-08 Ian Lance Taylor <iant@google.com>
|
2015-09-08 Ian Lance Taylor <iant@google.com>
|
||||||
|
|
||||||
PR other/67457
|
PR other/67457
|
||||||
|
|
|
@ -44,7 +44,8 @@ POSSIBILITY OF SUCH DAMAGE. */
|
||||||
backtrace functions may not be safely invoked from a signal
|
backtrace functions may not be safely invoked from a signal
|
||||||
handler. */
|
handler. */
|
||||||
|
|
||||||
/* Allocate memory like malloc. */
|
/* Allocate memory like malloc. If ERROR_CALLBACK is NULL, don't
|
||||||
|
report an error. */
|
||||||
|
|
||||||
void *
|
void *
|
||||||
backtrace_alloc (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
backtrace_alloc (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||||
|
@ -55,7 +56,10 @@ backtrace_alloc (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||||
|
|
||||||
ret = malloc (size);
|
ret = malloc (size);
|
||||||
if (ret == NULL)
|
if (ret == NULL)
|
||||||
error_callback (data, "malloc", errno);
|
{
|
||||||
|
if (error_callback)
|
||||||
|
error_callback (data, "malloc", errno);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
#include "unwind.h"
|
#include "unwind.h"
|
||||||
#include "backtrace.h"
|
#include "backtrace.h"
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
/* The main backtrace_full routine. */
|
/* The main backtrace_full routine. */
|
||||||
|
|
||||||
|
@ -53,6 +54,8 @@ struct backtrace_data
|
||||||
void *data;
|
void *data;
|
||||||
/* Value to return from backtrace_full. */
|
/* Value to return from backtrace_full. */
|
||||||
int ret;
|
int ret;
|
||||||
|
/* Whether there is any memory available. */
|
||||||
|
int can_alloc;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Unwind library callback routine. This is passed to
|
/* Unwind library callback routine. This is passed to
|
||||||
|
@ -80,8 +83,11 @@ unwind (struct _Unwind_Context *context, void *vdata)
|
||||||
if (!ip_before_insn)
|
if (!ip_before_insn)
|
||||||
--pc;
|
--pc;
|
||||||
|
|
||||||
bdata->ret = backtrace_pcinfo (bdata->state, pc, bdata->callback,
|
if (!bdata->can_alloc)
|
||||||
bdata->error_callback, bdata->data);
|
bdata->ret = bdata->callback (bdata->data, pc, NULL, 0, NULL);
|
||||||
|
else
|
||||||
|
bdata->ret = backtrace_pcinfo (bdata->state, pc, bdata->callback,
|
||||||
|
bdata->error_callback, bdata->data);
|
||||||
if (bdata->ret != 0)
|
if (bdata->ret != 0)
|
||||||
return _URC_END_OF_STACK;
|
return _URC_END_OF_STACK;
|
||||||
|
|
||||||
|
@ -96,6 +102,7 @@ backtrace_full (struct backtrace_state *state, int skip,
|
||||||
backtrace_error_callback error_callback, void *data)
|
backtrace_error_callback error_callback, void *data)
|
||||||
{
|
{
|
||||||
struct backtrace_data bdata;
|
struct backtrace_data bdata;
|
||||||
|
void *p;
|
||||||
|
|
||||||
bdata.skip = skip + 1;
|
bdata.skip = skip + 1;
|
||||||
bdata.state = state;
|
bdata.state = state;
|
||||||
|
@ -103,6 +110,18 @@ backtrace_full (struct backtrace_state *state, int skip,
|
||||||
bdata.error_callback = error_callback;
|
bdata.error_callback = error_callback;
|
||||||
bdata.data = data;
|
bdata.data = data;
|
||||||
bdata.ret = 0;
|
bdata.ret = 0;
|
||||||
|
|
||||||
|
/* If we can't allocate any memory at all, don't try to produce
|
||||||
|
file/line information. */
|
||||||
|
p = backtrace_alloc (state, 4096, NULL, NULL);
|
||||||
|
if (p == NULL)
|
||||||
|
bdata.can_alloc = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
backtrace_free (state, p, 4096, NULL, NULL);
|
||||||
|
bdata.can_alloc = 1;
|
||||||
|
}
|
||||||
|
|
||||||
_Unwind_Backtrace (unwind, &bdata);
|
_Unwind_Backtrace (unwind, &bdata);
|
||||||
return bdata.ret;
|
return bdata.ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -201,13 +201,15 @@ extern int backtrace_close (int descriptor,
|
||||||
extern void backtrace_qsort (void *base, size_t count, size_t size,
|
extern void backtrace_qsort (void *base, size_t count, size_t size,
|
||||||
int (*compar) (const void *, const void *));
|
int (*compar) (const void *, const void *));
|
||||||
|
|
||||||
/* Allocate memory. This is like malloc. */
|
/* Allocate memory. This is like malloc. If ERROR_CALLBACK is NULL,
|
||||||
|
this does not report an error, it just returns NULL. */
|
||||||
|
|
||||||
extern void *backtrace_alloc (struct backtrace_state *state, size_t size,
|
extern void *backtrace_alloc (struct backtrace_state *state, size_t size,
|
||||||
backtrace_error_callback error_callback,
|
backtrace_error_callback error_callback,
|
||||||
void *data) ATTRIBUTE_MALLOC;
|
void *data) ATTRIBUTE_MALLOC;
|
||||||
|
|
||||||
/* Free memory allocated by backtrace_alloc. */
|
/* Free memory allocated by backtrace_alloc. If ERROR_CALLBACK is
|
||||||
|
NULL, this does not report an error. */
|
||||||
|
|
||||||
extern void backtrace_free (struct backtrace_state *state, void *mem,
|
extern void backtrace_free (struct backtrace_state *state, void *mem,
|
||||||
size_t size,
|
size_t size,
|
||||||
|
|
|
@ -77,7 +77,8 @@ backtrace_free_locked (struct backtrace_state *state, void *addr, size_t size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate memory like malloc. */
|
/* Allocate memory like malloc. If ERROR_CALLBACK is NULL, don't
|
||||||
|
report an error. */
|
||||||
|
|
||||||
void *
|
void *
|
||||||
backtrace_alloc (struct backtrace_state *state,
|
backtrace_alloc (struct backtrace_state *state,
|
||||||
|
@ -140,7 +141,10 @@ backtrace_alloc (struct backtrace_state *state,
|
||||||
page = mmap (NULL, asksize, PROT_READ | PROT_WRITE,
|
page = mmap (NULL, asksize, PROT_READ | PROT_WRITE,
|
||||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||||
if (page == MAP_FAILED)
|
if (page == MAP_FAILED)
|
||||||
error_callback (data, "mmap", errno);
|
{
|
||||||
|
if (error_callback)
|
||||||
|
error_callback (data, "mmap", errno);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
size = (size + 7) & ~ (size_t) 7;
|
size = (size + 7) & ~ (size_t) 7;
|
||||||
|
|
Loading…
Add table
Reference in a new issue