Run process-dies-while-detaching.exp with SW watchpoint

Message ID 86zio3bkzb.fsf@gmail.com
State New, archived
Headers

Commit Message

Yao Qi Aug. 23, 2016, 2:47 p.m. UTC
  Hi,
I see the following fail when I run tests on some ARM board without
HW watchpoint support,

(gdb) watch globalvar^M
Watchpoint 2: globalvar^M
(gdb) FAIL: gdb.threads/process-dies-while-detaching.exp: single-process: detach: watchpoint: watch globalvar

I think we should run test_detach_watch with both HW watchpoint and SW
watchpoint.  I modified it, as the patch shown below, but the
test_detach_watch with SW watchpoint causes some test fails even on
x86_64,

Thread 12 "process-dies-wh" hit Temporary breakpoint 3, 0x00002aaaaafaf2d0 in _exit () from /lib/x86_64-linux-gnu/libc.so.6^M
(gdb) PASS: gdb.threads/process-dies-while-detaching.exp: single-process: continue: watchpoint hw=0: continue to breakpoint: _exit
continue^M
Continuing.^M
Cannot find user-level thread for LWP 2363: generic error^M
(gdb) FAIL: gdb.threads/process-dies-while-detaching.exp: single-process: continue: watchpoint hw=0: continue

When the error is thrown, the stack backtrace is 

(gdb) bt 10
#0  thread_from_lwp (ptid=...) at /home/yao/SourceCode/gnu/gdb/git/gdb/linux-thread-db.c:356
#1  0x0000000000460fb4 in thread_db_wait (ops=<optimised out>, ptid=..., ourstatus=0x7fff702c0510, options=1)
    at /home/yao/SourceCode/gnu/gdb/git/gdb/linux-thread-db.c:1146
#2  0x00000000005b69cd in delegate_wait (self=<optimised out>, arg1=..., arg2=<optimised out>, arg3=<optimised out>)
    at /home/yao/SourceCode/gnu/gdb/git/gdb/target-delegates.c:116
#3  0x00000000005c5bb4 in target_wait (ptid=..., status=status@entry=0x7fff702c0510, options=options@entry=1)
    at /home/yao/SourceCode/gnu/gdb/git/gdb/target.c:2289
#4  0x0000000000578269 in do_target_wait (ptid=..., status=status@entry=0x7fff702c0510, options=1) at /home/yao/SourceCode/gnu/gdb/git/gdb/infrun.c:3641
#5  0x0000000000583a1b in fetch_inferior_event (client_data=<optimised out>) at /home/yao/SourceCode/gnu/gdb/git/gdb/infrun.c:3952
#6  0x0000000000598cd5 in gdb_wait_for_event (block=block@entry=0) at /home/yao/SourceCode/gnu/gdb/git/gdb/event-loop.c:859
#7  0x0000000000598ee5 in gdb_do_one_event () at /home/yao/SourceCode/gnu/gdb/git/gdb/event-loop.c:322
#8  0x0000000000598f55 in start_event_loop () at /home/yao/SourceCode/gnu/gdb/git/gdb/event-loop.c:371
#9  0x0000000000592d18 in captured_command_loop (data=data@entry=0x0) at /home/yao/SourceCode/gnu/gdb/git/gdb/main.c:324

and the "ourstatus" got from beneath->to_wait is

(gdb) p *ourstatus
$1 = {kind = TARGET_WAITKIND_STOPPED, value = {integer = 5, sig = GDB_SIGNAL_TRAP, related_pid = {pid = 5, lwp = 0, tid = 0}, 
    execd_pathname = 0x5 <error: Cannot access memory at address 0x5>, syscall_number = 5}}

looks linux-nat target thinks the thread is stopped, but thread-db can't
find the thread.  Is it a known problem (in gdb or glibc)?
  

Comments

Pedro Alves Aug. 23, 2016, 3:20 p.m. UTC | #1
On 08/23/2016 03:47 PM, Yao Qi wrote:
> 
> Hi,
> I see the following fail when I run tests on some ARM board without
> HW watchpoint support,
> 
> (gdb) watch globalvar^M
> Watchpoint 2: globalvar^M
> (gdb) FAIL: gdb.threads/process-dies-while-detaching.exp: single-process: detach: watchpoint: watch globalvar
> 
> I think we should run test_detach_watch with both HW watchpoint and SW
> watchpoint.  I modified it, as the patch shown below, but the
> test_detach_watch with SW watchpoint causes some test fails even on
> x86_64,
> 
> Thread 12 "process-dies-wh" hit Temporary breakpoint 3, 0x00002aaaaafaf2d0 in _exit () from /lib/x86_64-linux-gnu/libc.so.6^M
> (gdb) PASS: gdb.threads/process-dies-while-detaching.exp: single-process: continue: watchpoint hw=0: continue to breakpoint: _exit
> continue^M
> Continuing.^M
> Cannot find user-level thread for LWP 2363: generic error^M
> (gdb) FAIL: gdb.threads/process-dies-while-detaching.exp: single-process: continue: watchpoint hw=0: continue
> 
> When the error is thrown, the stack backtrace is 
> 
> (gdb) bt 10
> #0  thread_from_lwp (ptid=...) at /home/yao/SourceCode/gnu/gdb/git/gdb/linux-thread-db.c:356
> #1  0x0000000000460fb4 in thread_db_wait (ops=<optimised out>, ptid=..., ourstatus=0x7fff702c0510, options=1)
>     at /home/yao/SourceCode/gnu/gdb/git/gdb/linux-thread-db.c:1146
> #2  0x00000000005b69cd in delegate_wait (self=<optimised out>, arg1=..., arg2=<optimised out>, arg3=<optimised out>)
>     at /home/yao/SourceCode/gnu/gdb/git/gdb/target-delegates.c:116
> #3  0x00000000005c5bb4 in target_wait (ptid=..., status=status@entry=0x7fff702c0510, options=options@entry=1)
>     at /home/yao/SourceCode/gnu/gdb/git/gdb/target.c:2289
> #4  0x0000000000578269 in do_target_wait (ptid=..., status=status@entry=0x7fff702c0510, options=1) at /home/yao/SourceCode/gnu/gdb/git/gdb/infrun.c:3641
> #5  0x0000000000583a1b in fetch_inferior_event (client_data=<optimised out>) at /home/yao/SourceCode/gnu/gdb/git/gdb/infrun.c:3952
> #6  0x0000000000598cd5 in gdb_wait_for_event (block=block@entry=0) at /home/yao/SourceCode/gnu/gdb/git/gdb/event-loop.c:859
> #7  0x0000000000598ee5 in gdb_do_one_event () at /home/yao/SourceCode/gnu/gdb/git/gdb/event-loop.c:322
> #8  0x0000000000598f55 in start_event_loop () at /home/yao/SourceCode/gnu/gdb/git/gdb/event-loop.c:371
> #9  0x0000000000592d18 in captured_command_loop (data=data@entry=0x0) at /home/yao/SourceCode/gnu/gdb/git/gdb/main.c:324
> 
> and the "ourstatus" got from beneath->to_wait is
> 
> (gdb) p *ourstatus
> $1 = {kind = TARGET_WAITKIND_STOPPED, value = {integer = 5, sig = GDB_SIGNAL_TRAP, related_pid = {pid = 5, lwp = 0, tid = 0}, 
>     execd_pathname = 0x5 <error: Cannot access memory at address 0x5>, syscall_number = 5}}
> 
> looks linux-nat target thinks the thread is stopped, but thread-db can't
> find the thread.  Is it a known problem (in gdb or glibc)?
> 

Doesn't this just mean that the process died meanwhile?
That's the point of the test.  /proc/TID/status probably shows
that the thread is now zombie.

BTW, software watchpoints aren't defined very well with threads,
but, it sounds like you'd get the same problem if you single-step
all the way to exit instead of "continue", which in effect is what
a software watchpoint does.

Thanks,
Pedro Alves
  
Yao Qi Aug. 24, 2016, 10:27 a.m. UTC | #2
On Tue, Aug 23, 2016 at 4:20 PM, Pedro Alves <palves@redhat.com> wrote:
>>
>> looks linux-nat target thinks the thread is stopped, but thread-db can't
>> find the thread.  Is it a known problem (in gdb or glibc)?
>>
>
> Doesn't this just mean that the process died meanwhile?
> That's the point of the test.  /proc/TID/status probably shows
> that the thread is now zombie.

Yes, I know what happened there, but not sure what is the best place
to fix the problem.  IIUC, we need to fix GDB somewhere to handle
such case that linux-nat thinks the thread is stopped, but thread-db
can't find it, is it right?
  

Patch

diff --git a/gdb/testsuite/gdb.threads/process-dies-while-detaching.exp b/gdb/testsuite/gdb.threads/process-dies-while-detaching.exp
index 52dc8dd..39cba31 100644
--- a/gdb/testsuite/gdb.threads/process-dies-while-detaching.exp
+++ b/gdb/testsuite/gdb.threads/process-dies-while-detaching.exp
@@ -209,10 +209,12 @@  proc test_detach {multi_process cmd} {
     }
 }
 
-# Same as test_detach, except set a watchpoint before detaching.
+# Same as test_detach, except set a watchpoint before detaching.  HW
+# is true if hardware watchpoint is used.
 
-proc test_detach_watch {multi_process cmd} {
-    with_test_prefix "watchpoint" {
+proc test_detach_watch {hw multi_process cmd} {
+
+    with_test_prefix "watchpoint hw=$hw" {
 	global binfile decimal
 
 	clean_restart ${binfile}
@@ -230,15 +232,25 @@  proc test_detach_watch {multi_process cmd} {
 	    gdb_continue_to_breakpoint "child_function" ".*"
 	}
 
+	if { ! $hw } {
+	    gdb_test_no_output "set can-use-hw-watchpoints 0" ""
+	}
 	# Set a watchpoint in the child.
-	gdb_test "watch globalvar" ".* watchpoint $decimal: globalvar"
+	gdb_test "watch globalvar" ".*\[Ww\]atchpoint $decimal: globalvar"
 
 	# Continue to the _exit breakpoint.  This arms the watchpoint
 	# registers in all threads.  Detaching will thus need to clear
 	# them out, and handle the case of the thread disappearing
 	# while doing that (on targets that need to detach from each
 	# thread individually).
-	continue_to_exit_bp
+	if { ! $hw } {
+	    # Software watchpoint is quite slow.
+	    with_timeout_factor 10 {
+		continue_to_exit_bp
+	    }
+	} else {
+	    continue_to_exit_bp
+	}
 
 	do_detach $multi_process $cmd
     }
@@ -313,7 +325,11 @@  proc do_test {multi_process cmd} {
     }
 
     test_detach $multi_process $cmd
-    test_detach_watch $multi_process $cmd
+    if { ![target_info exists gdb,no_hardware_watchpoints] } {
+	test_detach_watch 1 $multi_process $cmd
+    }
+    test_detach_watch 0 $multi_process $cmd
+
     test_detach_killed_outside $multi_process $cmd
 }