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>
|
||||
|
||||
PR other/67457
|
||||
|
|
|
@ -44,7 +44,8 @@ POSSIBILITY OF SUCH DAMAGE. */
|
|||
backtrace functions may not be safely invoked from a signal
|
||||
handler. */
|
||||
|
||||
/* Allocate memory like malloc. */
|
||||
/* Allocate memory like malloc. If ERROR_CALLBACK is NULL, don't
|
||||
report an error. */
|
||||
|
||||
void *
|
||||
backtrace_alloc (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||
|
@ -55,7 +56,10 @@ backtrace_alloc (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
|||
|
||||
ret = malloc (size);
|
||||
if (ret == NULL)
|
||||
error_callback (data, "malloc", errno);
|
||||
{
|
||||
if (error_callback)
|
||||
error_callback (data, "malloc", errno);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE. */
|
|||
|
||||
#include "unwind.h"
|
||||
#include "backtrace.h"
|
||||
#include "internal.h"
|
||||
|
||||
/* The main backtrace_full routine. */
|
||||
|
||||
|
@ -53,6 +54,8 @@ struct backtrace_data
|
|||
void *data;
|
||||
/* Value to return from backtrace_full. */
|
||||
int ret;
|
||||
/* Whether there is any memory available. */
|
||||
int can_alloc;
|
||||
};
|
||||
|
||||
/* Unwind library callback routine. This is passed to
|
||||
|
@ -80,8 +83,11 @@ unwind (struct _Unwind_Context *context, void *vdata)
|
|||
if (!ip_before_insn)
|
||||
--pc;
|
||||
|
||||
bdata->ret = backtrace_pcinfo (bdata->state, pc, bdata->callback,
|
||||
bdata->error_callback, bdata->data);
|
||||
if (!bdata->can_alloc)
|
||||
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)
|
||||
return _URC_END_OF_STACK;
|
||||
|
||||
|
@ -96,6 +102,7 @@ backtrace_full (struct backtrace_state *state, int skip,
|
|||
backtrace_error_callback error_callback, void *data)
|
||||
{
|
||||
struct backtrace_data bdata;
|
||||
void *p;
|
||||
|
||||
bdata.skip = skip + 1;
|
||||
bdata.state = state;
|
||||
|
@ -103,6 +110,18 @@ backtrace_full (struct backtrace_state *state, int skip,
|
|||
bdata.error_callback = error_callback;
|
||||
bdata.data = data;
|
||||
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);
|
||||
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,
|
||||
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,
|
||||
backtrace_error_callback error_callback,
|
||||
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,
|
||||
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 *
|
||||
backtrace_alloc (struct backtrace_state *state,
|
||||
|
@ -140,7 +141,10 @@ backtrace_alloc (struct backtrace_state *state,
|
|||
page = mmap (NULL, asksize, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
if (page == MAP_FAILED)
|
||||
error_callback (data, "mmap", errno);
|
||||
{
|
||||
if (error_callback)
|
||||
error_callback (data, "mmap", errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
size = (size + 7) & ~ (size_t) 7;
|
||||
|
|
Loading…
Add table
Reference in a new issue