aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Brobecker <brobecker@adacore.com>2014-01-20 16:18:58 +0100
committerJoel Brobecker <brobecker@adacore.com>2014-01-27 07:01:09 +0400
commit25790f6fc128f0785a3568019727c0512adc079c (patch)
tree928cc318af562be84f63955e70e901032ee6bd18
parentcc64f6178ed618d3bd7905f20aa8cc76571fbede (diff)
downloadgdb-25790f6fc128f0785a3568019727c0512adc079c.zip
gdb-25790f6fc128f0785a3568019727c0512adc079c.tar.gz
gdb-25790f6fc128f0785a3568019727c0512adc079c.tar.bz2
Remove assert in procfs.c::procfs_make_note_section (x86-solaris)
On x86-solaris, the gcore command sometimes triggers the following internal error: (gdb) gcore /[...]/procfs.c:5523: internal-error: procfs_make_note_section: Assertion `thread_args.note_data != note_data' failed. The problem is extremely elusive, for reasons that will become clearer as I explain what is going on. The program used to produce this issue was really simple: | void break_me (void) { } | | int | main (void) | { | break_me (); | return 0; | } The procfs_make_note_section builds a buffer incrementally with the contents of the core's notes section. The interesting bits are: char *note_data = NULL; [...] note_data = (char *) elfcore_write_prpsinfo (obfd, note_data, note_size, fname, psargs); This is the first call to bfd's elfcore which initializes note_data. After that, we have a few more calls, which keep updating notes_data and note_size, but our interest lies in the following part of the function: thread_args.note_data = note_data; [...] proc_iterate_over_threads (pi, procfs_corefile_thread_callback, &thread_args); /* There should be always at least one thread. */ gdb_assert (thread_args.note_data != note_data); The comment implies that the assert is to verify that our loop iterated over at least one thread. The check is relying on the fact that the notes_data returned by the elfcore module changes at each iteration, via (in procfs_corefile_thread_callback): args->note_data = procfs_do_thread_registers (args->obfd, ptid, args->note_data, args->note_size, args->stop_signal); (which calls elfcore_write_lwpstatus). But, while it happens most of the time, thanks to a call to realloc in elfcore_write_note (the function that actually appends the data at the end of the notes buffer),... buf = (char *) realloc (buf, *bufsiz + newspace); ... this is by no means guarantied. In fact, under the right circumstances, the buffer was grown twice without changing addresses. Unfortunately, the circumstances are very sensitive, thus making this bug very elusive. This patch fixes the problem by simply removing the assert. This means we're losing the assertion that there is at least one thread, but I think that's OK. If we still want to keep the assertion, we have the option of either checking the buffer size, or else adding a boolean flag in the context structure that we'd set to true as soon as we have a thread. gdb/ChangeLog: * procfs.c (procfs_make_note_section): Remove assertion and associated comment.
-rw-r--r--gdb/ChangeLog5
-rw-r--r--gdb/procfs.c3
2 files changed, 5 insertions, 3 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 504858d..3f47aff 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,8 @@
+2014-01-27 Joel Brobecker <brobecker@adacore.com>
+
+ * procfs.c (procfs_make_note_section): Remove assertion and
+ associated comment.
+
2014-01-24 Yao Qi <yao@codesourcery.com>
* remote.c (remote_read_bytes): Change type of len to ULONGEST.
diff --git a/gdb/procfs.c b/gdb/procfs.c
index 0ed788e..2383366 100644
--- a/gdb/procfs.c
+++ b/gdb/procfs.c
@@ -5518,9 +5518,6 @@ procfs_make_note_section (bfd *obfd, int *note_size)
thread_args.stop_signal = stop_signal;
proc_iterate_over_threads (pi, procfs_corefile_thread_callback,
&thread_args);
-
- /* There should be always at least one thread. */
- gdb_assert (thread_args.note_data != note_data);
note_data = thread_args.note_data;
auxv_len = target_read_alloc (&current_target, TARGET_OBJECT_AUXV,