]>
Commit | Line | Data |
---|---|---|
3a58abaf AM |
1 | 2005-02-28 Jeff Johnston <jjohnstn@redhat.com> |
2 | ||
3 | * config/i386/nm-linux.h: Change dr register routines to | |
4 | accept a ptid_t first argument. Change all calling macros | |
5 | to default the inferior_ptid for the first argument. | |
6 | (i386_linux_insert_watchpoint): New prototype. | |
7 | (i386_linux_remove_watchpoint, i386_linux_insert_hw_breakpoint): Ditto. | |
8 | (i386_linux_remove_hw_breakpoint): Ditto. | |
9 | (target_insert_watchpoint, target_remove_watchpoint): Undef and | |
10 | override. | |
11 | (target_insert_hw_breakpoint, target_remove_hw_breakpoint): Ditto. | |
12 | * config/i386/nm-linux64.h: Ditto except add amd64 versions of | |
13 | the watchpoint/hw-breakpoint insert/remove routines. | |
14 | * i386-nat.c: Include "inferior.h" to define inferior_ptid. | |
15 | * i386-linux-nat.c: Change all dr get/set routines to accept | |
16 | ptid_t as first argument and to use this argument to determine | |
17 | the tid for PTRACE. | |
18 | (i386_linux_set_debug_regs_for_thread): New function. | |
19 | (i386_linux_sync_debug_registers_callback): Ditto. | |
20 | (i386_linux_sync_debug_registers_across_threads): Ditto. | |
21 | (i386_linux_insert_watchpoint, i386_linux_remove_watchpoint): Ditto. | |
22 | (i386_linux_hw_breakpoint, i386_linux_remove_hw_breakpoint): Ditto. | |
23 | (i386_linux_new_thread): Ditto. | |
24 | (_initialize_i386_linux_nat): Ditto. | |
25 | * amd64-linux-nat.c: Change all dr get/set routines to accept | |
26 | ptid_t as first argument and to use this argument to determine | |
27 | the tid for PTRACE. | |
28 | (amd64_linux_set_debug_regs_for_thread): New function. | |
29 | (amd64_linux_sync_debug_registers_callback): Ditto. | |
30 | (amd64_linux_sync_debug_registers_across_threads): Ditto. | |
31 | (amd64_linux_insert_watchpoint, amd64_linux_remove_watchpoint): Ditto. | |
32 | (amd64_linux_hw_breakpoint, amd64_linux_remove_hw_breakpoint): Ditto. | |
33 | (amd64_linux_new_thread): Ditto. | |
34 | (_initialize_amd64_linux_nat): Register linux new thread observer. | |
35 | * testsuite/gdb.threads/watchthreads2.c: New test case. | |
36 | * testsuite/gdb.threads/watchthreads2.exp: Ditto. | |
37 | ||
38 | [ With recent upstream GDB (6.8) reduced only to the testcase. ] | |
39 | ||
40 | FIXME: The testcase does not expects multiple watchpoints hits per one stop. | |
41 | ||
42 | Index: gdb-6.5/gdb/testsuite/gdb.threads/watchthreads2.c | |
43 | =================================================================== | |
44 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | |
7566401a | 45 | +++ gdb-6.5/gdb/testsuite/gdb.threads/watchthreads-threaded.c 2006-07-12 01:54:29.000000000 -0300 |
3a58abaf AM |
46 | @@ -0,0 +1,66 @@ |
47 | +/* This testcase is part of GDB, the GNU debugger. | |
48 | + | |
49 | + Copyright 2002, 2003, 2004, 2005 Free Software Foundation, Inc. | |
50 | + | |
51 | + This program is free software; you can redistribute it and/or modify | |
52 | + it under the terms of the GNU General Public License as published by | |
53 | + the Free Software Foundation; either version 2 of the License, or | |
54 | + (at your option) any later version. | |
55 | + | |
56 | + This program is distributed in the hope that it will be useful, | |
57 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
58 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
59 | + GNU General Public License for more details. | |
60 | + | |
61 | + You should have received a copy of the GNU General Public License | |
62 | + along with this program; if not, write to the Free Software | |
63 | + Foundation, Inc., 59 Temple Place - Suite 330, | |
64 | + Boston, MA 02111-1307, USA. | |
65 | + | |
66 | + This file is copied from schedlock.c. */ | |
67 | + | |
68 | +#include <stdio.h> | |
69 | +#include <unistd.h> | |
70 | +#include <stdlib.h> | |
71 | +#include <pthread.h> | |
72 | + | |
73 | +void *thread_function(void *arg); /* Pointer to function executed by each thread */ | |
74 | + | |
75 | +#define NUM 5 | |
76 | + | |
77 | +unsigned int args[NUM+1]; | |
78 | + | |
79 | +int main() { | |
80 | + int res; | |
81 | + pthread_t threads[NUM]; | |
82 | + void *thread_result; | |
83 | + long i; | |
84 | + | |
85 | + for (i = 0; i < NUM; i++) | |
86 | + { | |
87 | + args[i] = 1; /* Init value. */ | |
88 | + res = pthread_create(&threads[i], | |
89 | + NULL, | |
90 | + thread_function, | |
91 | + (void *) i); | |
92 | + } | |
93 | + | |
94 | + args[i] = 1; | |
95 | + thread_function ((void *) i); | |
96 | + | |
97 | + exit(EXIT_SUCCESS); | |
98 | +} | |
99 | + | |
100 | +void *thread_function(void *arg) { | |
101 | + int my_number = (long) arg; | |
102 | + int *myp = (int *) &args[my_number]; | |
103 | + | |
104 | + /* Don't run forever. Run just short of it :) */ | |
105 | + while (*myp > 0) | |
106 | + { | |
107 | + (*myp) ++; usleep (1); /* Loop increment. */ | |
108 | + } | |
109 | + | |
110 | + pthread_exit(NULL); | |
111 | +} | |
112 | + | |
113 | Index: gdb-6.5/gdb/testsuite/gdb.threads/watchthreads2.exp | |
114 | =================================================================== | |
115 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | |
7566401a | 116 | +++ gdb-6.5/gdb/testsuite/gdb.threads/watchthreads-threaded.exp 2006-07-12 01:54:29.000000000 -0300 |
3a58abaf AM |
117 | @@ -0,0 +1,133 @@ |
118 | +# This testcase is part of GDB, the GNU debugger. | |
119 | + | |
120 | +# Copyright 2005 Free Software Foundation, Inc. | |
121 | + | |
122 | +# This program is free software; you can redistribute it and/or modify | |
123 | +# it under the terms of the GNU General Public License as published by | |
124 | +# the Free Software Foundation; either version 2 of the License, or | |
125 | +# (at your option) any later version. | |
126 | +# | |
127 | +# This program is distributed in the hope that it will be useful, | |
128 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
129 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
130 | +# GNU General Public License for more details. | |
131 | +# | |
132 | +# You should have received a copy of the GNU General Public License | |
133 | +# along with this program; if not, write to the Free Software | |
134 | +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
135 | + | |
136 | +# Check that GDB can support multiple watchpoints across threads. | |
137 | + | |
138 | +if $tracelevel { | |
139 | + strace $tracelevel | |
140 | +} | |
141 | + | |
142 | +set prms_id 0 | |
143 | +set bug_id 0 | |
144 | + | |
145 | +# This test verifies that a watchpoint is detected in the proper thread | |
146 | +# so the test is only meaningful on a system with hardware watchpoints. | |
147 | +if [target_info exists gdb,no_hardware_watchpoints] { | |
148 | + return 0; | |
149 | +} | |
150 | + | |
151 | +set testfile "watchthreads2" | |
152 | +set srcfile ${testfile}.c | |
153 | +set binfile ${objdir}/${subdir}/${testfile} | |
154 | +if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } { | |
155 | + return -1 | |
156 | +} | |
157 | + | |
158 | +gdb_exit | |
159 | +gdb_start | |
160 | +gdb_reinitialize_dir $srcdir/$subdir | |
161 | +gdb_load ${binfile} | |
162 | + | |
163 | +gdb_test "set can-use-hw-watchpoints 1" "" "" | |
164 | + | |
165 | +# | |
166 | +# Run to `main' where we begin our tests. | |
167 | +# | |
168 | + | |
169 | +if ![runto_main] then { | |
170 | + gdb_suppress_tests | |
171 | +} | |
172 | + | |
173 | +set args_2 0 | |
174 | +set args_3 0 | |
175 | + | |
176 | +gdb_breakpoint "thread_function" | |
177 | +gdb_continue_to_breakpoint "thread_function" | |
178 | +gdb_test "disable 2" "" | |
179 | + | |
180 | +gdb_test_multiple "p args\[2\]" "get initial args2" { | |
181 | + -re "\\\$\[0-9\]* = (.*)$gdb_prompt $" { | |
182 | + set init_args_2 $expect_out(1,string) | |
183 | + pass "get initial args2" | |
184 | + } | |
185 | +} | |
186 | + | |
187 | +gdb_test_multiple "p args\[3\]" "get initial args3" { | |
188 | + -re "\\\$\[0-9\]* = (.*)$gdb_prompt $" { | |
189 | + set init_args_3 $expect_out(1,string) | |
190 | + pass "get initial args3" | |
191 | + } | |
192 | +} | |
193 | + | |
194 | +set args_2 $init_args_2 | |
195 | +set args_3 $init_args_3 | |
196 | + | |
197 | +# Watch values that will be modified by distinct threads. | |
198 | +gdb_test "watch args\[2\]" "Hardware watchpoint 3: args\\\[2\\\]" | |
199 | +gdb_test "watch args\[3\]" "Hardware watchpoint 4: args\\\[3\\\]" | |
200 | + | |
201 | +set init_line [expr [gdb_get_line_number "Init value"]+1] | |
202 | +set inc_line [gdb_get_line_number "Loop increment"] | |
203 | + | |
204 | +# Loop and continue to allow both watchpoints to be triggered. | |
205 | +for {set i 0} {$i < 30} {incr i} { | |
206 | + set test_flag 0 | |
207 | + gdb_test_multiple "continue" "threaded watch loop" { | |
208 | + -re "Hardware watchpoint 3: args\\\[2\\\].*Old value = 0.*New value = 1.*main \\\(\\\) at .*watchthreads2.c:$init_line.*$gdb_prompt $" | |
209 | + { set args_2 1; set test_flag 1 } | |
210 | + -re "Hardware watchpoint 4: args\\\[3\\\].*Old value = 0.*New value = 1.*main \\\(\\\) at .*watchthreads2.c:$init_line.*$gdb_prompt $" | |
211 | + { set args_3 1; set test_flag 1 } | |
212 | + -re "Hardware watchpoint 3: args\\\[2\\\].*Old value = $args_2.*New value = [expr $args_2+1].*in thread_function \\\(arg=0x2\\\) at .*watchthreads2.c:$inc_line.*$gdb_prompt $" | |
213 | + { set args_2 [expr $args_2+1]; set test_flag 1 } | |
214 | + -re "Hardware watchpoint 4: args\\\[3\\\].*Old value = $args_3.*New value = [expr $args_3+1].*in thread_function \\\(arg=0x3\\\) at .*watchthreads2.c:$inc_line.*$gdb_prompt $" | |
215 | + { set args_3 [expr $args_3+1]; set test_flag 1 } | |
216 | + } | |
217 | + # If we fail above, don't bother continuing loop | |
218 | + if { $test_flag == 0 } { | |
219 | + set i 30; | |
220 | + } | |
221 | +} | |
222 | + | |
223 | +# Print success message if loop succeeded. | |
224 | +if { $test_flag == 1 } { | |
225 | + pass "threaded watch loop" | |
226 | +} | |
227 | + | |
228 | +# Verify that we hit first watchpoint in child thread. | |
229 | +set message "watchpoint on args\[2\] hit in thread" | |
230 | +if { $args_2 > 1 } { | |
231 | + pass $message | |
232 | +} else { | |
233 | + fail $message | |
234 | +} | |
235 | + | |
236 | +# Verify that we hit second watchpoint in child thread. | |
237 | +set message "watchpoint on args\[3\] hit in thread" | |
238 | +if { $args_3 > 1 } { | |
239 | + pass $message | |
240 | +} else { | |
241 | + fail $message | |
242 | +} | |
243 | + | |
244 | +# Verify that all watchpoint hits are accounted for. | |
245 | +set message "combination of threaded watchpoints = 30 + initial values" | |
246 | +if { [expr $args_2+$args_3] == [expr [expr 30+$init_args_2]+$init_args_3] } { | |
247 | + pass $message | |
248 | +} else { | |
249 | + fail $message | |
250 | +} |