summaryrefslogtreecommitdiff
path: root/libbacktrace
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2015-09-08 16:46:16 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2015-09-08 16:46:16 +0000
commit61ee636a6a1cbcf01d2ee7441d428d995266bcbd (patch)
treeeae6d20512a5643294e17bfb41e704ab2559be16 /libbacktrace
parent5553d0c3c6e8190b1738d56153b398e0da43fcfa (diff)
downloadgcc-61ee636a6a1cbcf01d2ee7441d428d995266bcbd.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@227533 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libbacktrace')
-rw-r--r--libbacktrace/ChangeLog14
-rw-r--r--libbacktrace/alloc.c8
-rw-r--r--libbacktrace/backtrace.c23
-rw-r--r--libbacktrace/internal.h6
-rw-r--r--libbacktrace/mmap.c8
5 files changed, 51 insertions, 8 deletions
diff --git a/libbacktrace/ChangeLog b/libbacktrace/ChangeLog
index 92ec7a13c4a..fb7e8b0aa79 100644
--- a/libbacktrace/ChangeLog
+++ b/libbacktrace/ChangeLog
@@ -1,6 +1,20 @@
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
* mmap.c (backtrace_alloc): Correct test for mmap failure.
2015-08-31 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
diff --git a/libbacktrace/alloc.c b/libbacktrace/alloc.c
index 143ef68ca51..772d3bfb8ad 100644
--- a/libbacktrace/alloc.c
+++ b/libbacktrace/alloc.c
@@ -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;
}
diff --git a/libbacktrace/backtrace.c b/libbacktrace/backtrace.c
index d352d27a400..d675e1e1062 100644
--- a/libbacktrace/backtrace.c
+++ b/libbacktrace/backtrace.c
@@ -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;
}
diff --git a/libbacktrace/internal.h b/libbacktrace/internal.h
index 30f99ca127f..b139e50f9e8 100644
--- a/libbacktrace/internal.h
+++ b/libbacktrace/internal.h
@@ -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,
diff --git a/libbacktrace/mmap.c b/libbacktrace/mmap.c
index 47c564f13f8..1910cb1f9eb 100644
--- a/libbacktrace/mmap.c
+++ b/libbacktrace/mmap.c
@@ -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;