OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [gdb/] [testsuite/] [gdb.threads/] [linux-dp.exp] - Blame information for rev 318

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
# Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
2
# Free Software Foundation, Inc.
3
 
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 3 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program.  If not, see .
16
 
17
# Please email any bugs, comments, and/or additions to this file to:
18
# bug-gdb@gnu.org
19
 
20
#### Dining Philosophers, on LinuxThreads - Jim Blandy 
21
####
22
#### At the moment, GDB's support for LinuxThreads is pretty
23
#### idiosyncratic --- GDB's output doesn't look much like the output
24
#### it produces for other thread implementations, messages appear at
25
#### different times, etc.  So these tests are specific to LinuxThreads.
26
####
27
#### However, if all goes well, Linux will soon have a libthread_db
28
#### interface, and GDB will manage it the same way it does other
29
#### libthread_db-based systems.  Then, we can adjust this file to
30
#### work with any such system.
31
 
32
### Other things we ought to test:
33
### stepping a thread while others are running
34
### killing and restarting
35
### quitting gracefully
36
 
37
if $tracelevel then {
38
        strace $tracelevel
39
}
40
 
41
set prms_id 0
42
set bug_id 0
43
 
44
# This only works with Linux configurations.
45
if ![istarget *-*-linux-gnu*] then {
46
    return
47
}
48
 
49
set testfile "linux-dp"
50
set srcfile ${testfile}.c
51
set binfile ${objdir}/${subdir}/${testfile}
52
if {[gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug libs=-lpthread}] != ""} {
53
    return -1
54
}
55
 
56
gdb_start
57
gdb_reinitialize_dir $srcdir/$subdir
58
gdb_load ${binfile}
59
send_gdb "set print sevenbit-strings\n" ; gdb_expect -re "$gdb_prompt $"
60
runto_main
61
 
62
# There should be no threads initially.
63
gdb_test "info threads" "" "info threads 1"
64
 
65
# Try stepping over the thread creation function.
66
gdb_breakpoint [gdb_get_line_number "linuxthreads.exp: create philosopher"]
67
set expect_manager -1
68
for {set i 0} {$i < 5} {incr i} {
69
    gdb_continue_to_breakpoint "about to create philosopher: $i"
70
    send_gdb "info threads\n"
71
    set threads_before {}
72
    gdb_expect {
73
        -re "info threads\r\n" {
74
            exp_continue
75
        }
76
        -re "^. +(\[0-9\]+ Thread \[-0-9a-fx\]+) \[^\n\]*\n" {
77
            verbose -log "found thread $expect_out(1,string)" 2
78
            lappend threads_before $expect_out(1,string)
79
            exp_continue
80
        }
81
        -re "^\[^\n\]*\n" {
82
            verbose -log "skipping line" 2
83
            exp_continue -continue_timer
84
        }
85
        -re "^$gdb_prompt $" {
86
        }
87
        timeout {
88
            fail "(timeout) info threads before: $i"
89
        }
90
    }
91
    send_gdb "next\n"
92
    set threads_created 0
93
    gdb_expect {
94
        -re "^next\r\n" {
95
            exp_continue
96
        }
97
        -re "^ *\[_!\] \[0-9\]* \[_!\]\r\n" {
98
            # Ignore program output.
99
            exp_continue -continue_timer
100
        }
101
        -re "^\\\[New \[^\]\n\]+\\\]\[^\n\]+\n" {
102
            incr threads_created
103
            exp_continue
104
        }
105
        -re "^189\[^\n\]+\n" {
106
            exp_continue
107
        }
108
        -re "^$gdb_prompt $" {
109
        }
110
        -re "Program received signal.*(Unknown signal|SIGUSR|Real-time event).*$gdb_prompt $" {
111
            # It would be nice if we could catch the message that GDB prints
112
            # when it first notices that the thread library doesn't support
113
            # debugging, or if we could explicitly ask GDB somehow.
114
            unsupported "This GDB does not support threads on this system."
115
            return -1
116
        }
117
        -re "$gdb_prompt $" {
118
        }
119
        timeout {
120
            fail "(timeout) create philosopher: $i"
121
        }
122
    }
123
    if { $threads_created == 0 } {
124
        # Not all targets announce new threads as they are created.
125
        # For example, the GDB
126
        # remote protocol target only finds out about threads when
127
        # they actually report some event like a breakpoint hit,
128
        # or when the user types 'info threads'.
129
        unsupported "create philosopher: $i"
130
    } elseif { $threads_created == 1 } {
131
        if { $expect_manager < 0 } {
132
            set expect_manager 0
133
        }
134
        pass "create philosopher: $i"
135
    } elseif { !$i && $threads_created == 2 } {
136
        # Two threads are created the first time in LinuxThreads,
137
        # where the second is the manager thread.  In NPTL, there is none.
138
        set expect_manager 1
139
        pass "create philosopher: $i"
140
    } else {
141
        fail "create philosopher: $i"
142
    }
143
 
144
    send_gdb "info threads\n"
145
    set threads_after {}
146
    gdb_expect {
147
        -re "info threads\r\n" {
148
            exp_continue
149
        }
150
        -re "^. +(\[0-9\]+ Thread \[-0-9a-fx\]+) \[^\n\]*\n" {
151
            set name $expect_out(1,string)
152
            for {set j 0} {$j != [llength $threads_before] } {incr j} {
153
                if {$name == [lindex $threads_before $j]} {
154
                    set threads_before [lreplace $threads_before $j $j]
155
                    set name ""
156
                    break
157
                }
158
            }
159
            if { $name != "" } {
160
                lappend threads_after $name
161
            }
162
            exp_continue
163
        }
164
        -re "^\[^\n\]*\n" {
165
            verbose -log "skipping line" 2
166
            exp_continue -continue_timer
167
        }
168
        -re "^$gdb_prompt $" {
169
            if { [llength $threads_before] != 0 } {
170
                fail "info threads after: $i"
171
            } elseif { !$i && [llength $threads_after] == 2 } {
172
                set expect_manager 1
173
                pass "info threads after: $i"
174
            } elseif { [llength $threads_after] == 1 } {
175
                if { $expect_manager < 0 } {
176
                    set expect_manager 0
177
                }
178
                pass "info threads after: $i"
179
            } else {
180
                fail "info threads after: $i"
181
            }
182
        }
183
        timeout {
184
            fail "(timeout) info threads after: $i"
185
        }
186
    }
187
 
188
}
189
 
190
set nthreads 6
191
 
192
# Run until there are some threads.
193
gdb_breakpoint [gdb_get_line_number "linuxthreads.exp: info threads 2"]
194
gdb_continue_to_breakpoint "main thread's sleep"
195
set info_threads_ptn ""
196
for {set i $nthreads} {$i > 0} {incr i -1} {
197
    append info_threads_ptn "$i Thread .*"
198
}
199
append info_threads_ptn "\[\r\n\]+$gdb_prompt $"
200
set info_threads_manager_ptn "[expr $nthreads + 1] Thread .*$info_threads_ptn"
201
 
202
gdb_test_multiple "info threads" "info threads 2" {
203
    -re "$info_threads_manager_ptn" {
204
        # We did see a manager thread.  Check that against what we expected.
205
        switch -exact -- $expect_manager {
206
            -1 {
207
                # We weren't sure whether to expect a manager thread.
208
                pass "info threads 2"
209
            }
210
            1 {
211
                # We were expecting a manager thread.
212
                pass "info threads 2"
213
            }
214
 
215
                # We were not expecting to see the manager thread.
216
                fail "info threads 2"
217
            }
218
        }
219
        set expect_manager 1
220
        incr nthreads
221
    }
222
    -re "$info_threads_ptn" {
223
        # We did not see a manager thread.  Check that against what we
224
        # expected.
225
        switch -exact -- $expect_manager {
226
            -1 {
227
                # We weren't sure whether to expect a manager thread.
228
                # Don't expect it from here on out.
229
                pass "info threads 2"
230
            }
231
            1 {
232
                # We were expecting a manager thread, but we didn't see one.
233
                fail "info threads 2"
234
            }
235
 
236
                # We were not expecting to see the manager thread.
237
                pass "info threads 2"
238
            }
239
        }
240
        set expect_manager 0
241
    }
242
}
243
 
244
 
245
# Try setting a thread-specific breakpoint.
246
gdb_breakpoint "print_philosopher thread 5"
247
gdb_continue_to_breakpoint "thread 5's print"
248
# When there is no debugging info available for the thread library,
249
# the backtrace entry for philosopher's caller looks like:
250
#    #1  0x4001c548 in pthread_create () from /lib/libpthread.so.0
251
# If you do have debug info, the output obviously depends more on the
252
# exact library in use; under NPTL, you get:
253
#    #2  0x0012b7fc in start_thread (arg=0x21) at pthread_create.c:264
254
gdb_test "where" "print_philosopher.*philosopher.* \(from .*libpthread\|at pthread_create\).*" \
255
        "first thread-specific breakpoint hit"
256
 
257
# Make sure it's catching the right thread.  Try hitting the
258
# breakpoint ten times, and make sure we don't get anyone else.
259
set only_five 1
260
for {set i 0} {$only_five > 0 && $i < 10} {incr i} {
261
    gdb_continue_to_breakpoint "thread 5's print, pass: $i"
262
    send_gdb "info threads\n"
263
    gdb_expect {
264
        -re "\\* 5 Thread .*  print_philosopher .*\r\n$gdb_prompt $" {
265
            # Okay this time.
266
        }
267
        -re ".*$gdb_prompt $" {
268
            set only_five 0
269
        }
270
        timeout {
271
            set only_five -1
272
        }
273
    }
274
}
275
 
276
set name "thread-specific breakpoint is thread-specific"
277
if {$only_five ==  1} { pass $name }
278
if {$only_five ==  0} { fail $name }
279
if {$only_five == -1} { fail "$name (timeout)" }
280
 
281
 
282
### Select a particular thread.
283
proc select_thread {thread} {
284
    global gdb_prompt
285
 
286
    send_gdb "thread $thread\n"
287
    gdb_expect {
288
        -re "\\\[Switching to thread .*\\\].*\r\n$gdb_prompt $" {
289
            pass "selected thread: $thread"
290
        }
291
        -re "$gdb_prompt $" {
292
            fail "selected thread: $thread"
293
        }
294
        timeout {
295
            fail "selected thread: $thread (timeout)"
296
        }
297
    }
298
}
299
 
300
### Select THREAD, check for a plausible backtrace, and make sure
301
### we're actually selecting a different philosopher each time.
302
### Return true if the thread had a stack which was not only
303
### acceptable, but interesting.  SEEN should be an array in which
304
### SEEN(N) exists iff we have found philosopher number N before.
305
 
306
set main_seen 0
307
set manager_seen 0
308
 
309
proc check_philosopher_stack {thread seen_name} {
310
    global gdb_prompt
311
    upvar $seen_name seen
312
    global main_seen
313
    global expect_manager manager_seen
314
 
315
    set name "philosopher is distinct: $thread"
316
    set interesting 0
317
 
318
    select_thread $thread
319
    send_gdb "where\n"
320
    gdb_expect {
321
        -re ".* in philosopher \\(data=(0x\[0-9a-f\]+).*\r\n$gdb_prompt $" {
322
            set data $expect_out(1,string)
323
            if {[info exists seen($data)]} {
324
                fail $name
325
            } else {
326
                pass $name
327
                set seen($data) yep
328
            }
329
            set interesting 1
330
        }
331
        -re ".* in __pthread_manager \\(.*$gdb_prompt $" {
332
            if {$manager_seen == 1} {
333
                fail "manager thread is distinct: $thread"
334
            } else {
335
                set manager_seen 1
336
                pass "manager thread is distinct: $thread"
337
            }
338
            set interesting 1
339
        }
340
        -re "pthread_start_thread.*\r\n$gdb_prompt $" {
341
            ## Maybe the thread hasn't started yet.
342
            pass $name
343
        }
344
        -re ".* in main \\(.*$gdb_prompt $" {
345
            if {$main_seen == 1} {
346
                fail "main is distinct: $thread"
347
            } else {
348
                set main_seen 1
349
                pass "main is distinct: $thread"
350
            }
351
            set interesting 1
352
        }
353
        -re " in \\?\\?.*\r\n$gdb_prompt $" {
354
            ## Sometimes we can't get a backtrace.  I'm going to call
355
            ## this a pass, since we do verify that at least one
356
            ## thread was interesting, so we can get more consistent
357
            ## test suite totals.  But in my heart, I think it should
358
            ## be an xfail.
359
            pass $name
360
        }
361
        -re "$gdb_prompt $" {
362
            fail $name
363
        }
364
        timeout {
365
            fail "$name (timeout)"
366
        }
367
    }
368
 
369
    return $interesting
370
}
371
 
372
set any_interesting 0
373
array set seen {}
374
unset seen
375
for {set i 1} {$i <= $nthreads} {incr i} {
376
    if [check_philosopher_stack $i seen] {
377
        set any_interesting 1
378
    }
379
}
380
 
381
if {$any_interesting} {
382
    pass "found an interesting thread"
383
} else {
384
    fail "found an interesting thread"
385
}
386
 
387
if {$manager_seen == $expect_manager} {
388
    pass "manager thread found (not found) when expected"
389
} else {
390
    fail "manager thread found (not found) when expected"
391
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.