This is the mail archive of the
gdb@sourceware.org
mailing list for the GDB project.
Re: Reg : gdb crash is seen while attaching a process to gdb.
- From: RAJESH DASARI <raajeshdasari at gmail dot com>
- To: Yao Qi <qiyaoltc at gmail dot com>
- Cc: GDB <gdb at sourceware dot org>, mukuntha dot rajaa at nokia dot com
- Date: Fri, 7 Apr 2017 14:09:53 +0530
- Subject: Re: Reg : gdb crash is seen while attaching a process to gdb.
- Authentication-results: sourceware.org; auth=none
- References: <CAPXMrf8TH66vZtp+9riDpDR4fBizip5-LQtZ9+1nSfVaywTLxg@mail.gmail.com> <CAH=s-PPcmOkY-yPuGsDbE0L=Q=SC9qjw9afTZnHfRE_oMPTzVA@mail.gmail.com> <728178DD-B9FD-4695-A7FF-F13B829DFD2E@gmail.com> <864lyfp0b7.fsf@gmail.com>
Hi,
I have recompiled the gdb with the given patch but still i see the issue ,
These are my observation when i see the gdb crash.
1. strace -e ptrace gdb -p 7978 <when i attach gdb with strace
enabled, attaching , dettaching and all the debugging operations were
successful>.
2. when i attach process with only gdb command like below
gdb -p 7878 ,
[New LWP 7879]
Couldn't write debug register: No such process.
(gdb) bt
#0 0xf5655ea0 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
Any idea why i am seeing couldn't write debug registers error and
Backtrace stopped: previous frame identical to this frame (corrupt
stack?) errors.
when i dettach the process in this state , i am getting the core dump
which i had reported in my previous mail .
Is this bug in gdb ,Could you someone please help me on how to proceed
further on this issue.
Regards,
Rajesh.
Thanks,
Rajesh Dasari.
On Mon, Mar 27, 2017 at 2:24 PM, Yao Qi <qiyaoltc@gmail.com> wrote:
> RAJESH DASARI <raajeshdasari@gmail.com> writes:
>
>> Thanks for your quick response . Could you please share those patches
>> , I will recompile the gdb with the patches and test the changes.
>
> Could you try the patch below on 7.12? If the patch doesn't work,
> please provide the GDB's stack backtrace on internal error.
>
> --
> Yao (齐尧)
> From 0621d3b4c0c665defc2166ee6240dc85f909275a Mon Sep 17 00:00:00 2001
> From: Yao Qi <yao.qi@linaro.org>
> Date: Mon, 27 Mar 2017 09:42:38 +0100
> Subject: [PATCH] Fix refcount of thread_info
>
> I build GDB with asan, and run test case hook-stop.exp, and threadapply.exp,
> I got the following asan error,
>
> =================================================================^M
> ^[[1m^[[31m==2291==ERROR: AddressSanitizer: heap-use-after-free on address 0x6160000999c4 at pc 0x000000826022 bp 0x7ffd28a8ff70 sp 0x7ffd28a8ff60^M
> ^[[1m^[[0m^[[1m^[[34mREAD of size 4 at 0x6160000999c4 thread T0^[[1m^[[0m^M
> #0 0x826021 in release_stop_context_cleanup ../../binutils-gdb/gdb/infrun.c:8203^M
> #1 0x72798a in do_my_cleanups ../../binutils-gdb/gdb/common/cleanups.c:154^M
> #2 0x727a32 in do_cleanups(cleanup*) ../../binutils-gdb/gdb/common/cleanups.c:176^M
> #3 0x826895 in normal_stop() ../../binutils-gdb/gdb/infrun.c:8381^M
> #4 0x815208 in fetch_inferior_event(void*) ../../binutils-gdb/gdb/infrun.c:4011^M
> #5 0x868aca in inferior_event_handler(inferior_event_type, void*) ../../binutils-gdb/gdb/inf-loop.c:44^M
> ....
> ^[[1m^[[32m0x6160000999c4 is located 68 bytes inside of 568-byte region [0x616000099980,0x616000099bb8)^M
> ^[[1m^[[0m^[[1m^[[35mfreed by thread T0 here:^[[1m^[[0m^M
> #0 0x7fb0bc1312ca in __interceptor_free (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x982ca)^M
> #1 0xb8c62f in xfree(void*) ../../binutils-gdb/gdb/common/common-utils.c:100^M
> #2 0x83df67 in free_thread ../../binutils-gdb/gdb/thread.c:207^M
> #3 0x83dfd2 in init_thread_list() ../../binutils-gdb/gdb/thread.c:223^M
> #4 0x805494 in kill_command ../../binutils-gdb/gdb/infcmd.c:2595^M
> ....
>
> Detaching from program: /home/yao.qi/SourceCode/gnu/build-with-asan/gdb/testsuite/outputs/gdb.threads/threadapply/threadapply, process 2399^M
> =================================================================^M
> ^[[1m^[[31m==2387==ERROR: AddressSanitizer: heap-use-after-free on address 0x6160000a98c0 at pc 0x00000083fd28 bp 0x7ffd401c3110 sp 0x7ffd401c3100^M
> ^[[1m^[[0m^[[1m^[[34mREAD of size 4 at 0x6160000a98c0 thread T0^[[1m^[[0m^M
> #0 0x83fd27 in thread_alive ../../binutils-gdb/gdb/thread.c:741^M
> #1 0x844277 in thread_apply_all_command ../../binutils-gdb/gdb/thread.c:1804^M
> ....
> ^M
> ^[[1m^[[32m0x6160000a98c0 is located 64 bytes inside of 568-byte region [0x6160000a9880,0x6160000a9ab8)^M
> ^[[1m^[[0m^[[1m^[[35mfreed by thread T0 here:^[[1m^[[0m^M
> #0 0x7f59a7e322ca in __interceptor_free (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x982ca)^M
> #1 0xb8c62f in xfree(void*) ../../binutils-gdb/gdb/common/common-utils.c:100^M
> #2 0x83df67 in free_thread ../../binutils-gdb/gdb/thread.c:207^M
> #3 0x83dfd2 in init_thread_list() ../../binutils-gdb/gdb/thread.c:223^M
>
> This patch fixes the issue by always checking refcount before decreasing it.
> If it is zero already, free the thread_info.
>
> gdb:
>
> 2017-03-27 Yao Qi <yao.qi@linaro.org>
>
> PR gdb/19942
> * gdbthread.h (free_thread): Declare.
> * infrun.c (release_stop_context_cleanup): If refcount is zero
> call free_thread.
> * thread.c (free_thread): Remove "static".
> (init_thread_list): If refcount is zero, call free_thread.
> (restore_current_thread_cleanup_dtor): Likewise.
> (set_thread_refcount): Likewise.
> ---
> gdb/gdbthread.h | 3 +++
> gdb/infrun.c | 7 ++++++-
> gdb/thread.c | 21 +++++++++++++++++----
> 3 files changed, 26 insertions(+), 5 deletions(-)
>
> diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h
> index 455cfd8..f89c6e1 100644
> --- a/gdb/gdbthread.h
> +++ b/gdb/gdbthread.h
> @@ -369,6 +369,9 @@ extern void delete_thread (ptid_t);
> exited, for example. */
> extern void delete_thread_silent (ptid_t);
>
> +/* Free TP. */
> +extern void free_thread (struct thread_info *tp);
> +
> /* Delete a step_resume_breakpoint from the thread database. */
> extern void delete_step_resume_breakpoint (struct thread_info *);
>
> diff --git a/gdb/infrun.c b/gdb/infrun.c
> index 5125ede..13b74bd 100644
> --- a/gdb/infrun.c
> +++ b/gdb/infrun.c
> @@ -8200,7 +8200,12 @@ release_stop_context_cleanup (void *arg)
> struct stop_context *sc = (struct stop_context *) arg;
>
> if (sc->thread != NULL)
> - sc->thread->refcount--;
> + {
> + if (sc->thread->refcount == 0)
> + free_thread (sc->thread);
> + else
> + sc->thread->refcount--;
> + }
> xfree (sc);
> }
>
> diff --git a/gdb/thread.c b/gdb/thread.c
> index 1e39ac4..36dc40f 100644
> --- a/gdb/thread.c
> +++ b/gdb/thread.c
> @@ -192,7 +192,7 @@ clear_thread_inferior_resources (struct thread_info *tp)
> thread_cancel_execution_command (tp);
> }
>
> -static void
> +void
> free_thread (struct thread_info *tp)
> {
> if (tp->priv)
> @@ -220,7 +220,10 @@ init_thread_list (void)
> for (tp = thread_list; tp; tp = tpnext)
> {
> tpnext = tp->next;
> - free_thread (tp);
> + if (tp->refcount == 0)
> + free_thread (tp);
> + else
> + tp->refcount--;
> }
>
> thread_list = NULL;
> @@ -1612,7 +1615,12 @@ restore_current_thread_cleanup_dtor (void *arg)
>
> tp = find_thread_ptid (old->inferior_ptid);
> if (tp)
> - tp->refcount--;
> + {
> + if (tp->refcount == 0)
> + free_thread (tp);
> + else
> + tp->refcount--;
> + }
> inf = find_inferior_id (old->inf_id);
> if (inf != NULL)
> inf->removable = old->was_removable;
> @@ -1629,7 +1637,12 @@ set_thread_refcount (void *data)
> = (struct thread_array_cleanup *) data;
>
> for (k = 0; k != ta_cleanup->count; k++)
> - ta_cleanup->tp_array[k]->refcount--;
> + {
> + if (ta_cleanup->tp_array[k]->refcount == 0)
> + free_thread (ta_cleanup->tp_array[k]);
> + else
> + ta_cleanup->tp_array[k]->refcount--;
> + }
> }
>
> struct cleanup *
> --
> 1.9.1