Re: Reg : gdb crash is seen while attaching a process to gdb.

RAJESH DASARI <[email protected]>
Newsgroups gmane.comp.gdb.devel
Message-ID <CAPXMrf_+cHn9sjFY-yXy==cNoGS98cSmcV+R9TVLbeExru+NWQ@mail.gmail.com>
Hi ,

I have raised a bug for the issue discussed in this mail chain,
https://sourceware.org/bugzilla/show_bug.cgi?id=21395 and i was able
to resolve the issue with minor code changes.

Could someone please provide  comments.

diff --git a/gdb/mips-linux-nat.c b/gdb/mips-linux-nat.c
index 9d22773..68641f8 100644
--- a/gdb/mips-linux-nat.c
+++ b/gdb/mips-linux-nat.c
@@ -634,9 +634,20 @@ mips_linux_new_thread (struct lwp_info *lp)
                                        &watch_readback_valid, 0))
     return;

+  long r;
+  r= ptrace (PTRACE_SET_WATCH_REGS, tid, &watch_mirror, NULL);
   tid = ptid_get_lwp (lp->ptid);
-  if (ptrace (PTRACE_SET_WATCH_REGS, tid, &watch_mirror, NULL) == -1)
-    perror_with_name (_("Couldn't write debug register"));
+  if ( r == -1L && errno == ESRCH )
+  {
+     /* sleep for a while to eliminate race condition on  update to kernel
+      * task structure with the process state (STOP state of thread).
+      */
+     usleep(10000);
+     if ( ptrace (PTRACE_SET_WATCH_REGS, tid, &watch_mirror, NULL) == -1 )
+     {
+        perror_with_name (_("Couldn't write debug register"));
+     }
+   }
 }

 /* Target to_insert_watchpoint implementation.  Try to insert a new
-- 
2.4.11



Thanks,
Rajesh Dasari.


On Fri, Apr 7, 2017 at 2:09 PM, RAJESH DASARI <[email protected]> wrote:
> 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 <[email protected]> wrote:
>> RAJESH DASARI <[email protected]> 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 <[email protected]>
>> 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  <[email protected]>
>>
>>         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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.