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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gdb/] [gdb-6.8/] [gdb/] [testsuite/] [gdb.threads/] [linux-dp.exp] - Blame information for rev 25

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 25 jlechner
# Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
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
        }
84
        -re "^$gdb_prompt $" {
85
        }
86
        timeout {
87
            fail "(timeout) info threads before: $i"
88
        }
89
    }
90
    send_gdb "next\n"
91
    set threads_created 0
92
    gdb_expect {
93
        -re "^next\r\n" {
94
            exp_continue
95
        }
96
        -re "^ *\[_!\] \[0-9\]* \[_!\]\r\n" {
97
            # Ignore program output.
98
            exp_continue -continue_timer
99
        }
100
        -re "^\\\[New \[^\]\n\]+\\\]\[^\n\]+\n" {
101
            incr threads_created
102
            exp_continue
103
        }
104
        -re "^189\[^\n\]+\n" {
105
            exp_continue
106
        }
107
        -re "^$gdb_prompt $" {
108
        }
109
        -re "Program received signal.*(Unknown signal|SIGUSR|Real-time event).*$gdb_prompt $" {
110
            # It would be nice if we could catch the message that GDB prints
111
            # when it first notices that the thread library doesn't support
112
            # debugging, or if we could explicitly ask GDB somehow.
113
            unsupported "This GDB does not support threads on this system."
114
            return -1
115
        }
116
        -re "$gdb_prompt $" {
117
        }
118
        timeout {
119
            fail "(timeout) create philosopher: $i"
120
        }
121
    }
122
    if { $threads_created == 0 } {
123
        # Not all targets announce new threads as they are created.
124
        # For example, the GDB
125
        # remote protocol target only finds out about threads when
126
        # they actually report some event like a breakpoint hit,
127
        # or when the user types 'info threads'.
128
        unsupported "create philosopher: $i"
129
    } elseif { $threads_created == 1 } {
130
        if { $expect_manager < 0 } {
131
            set expect_manager 0
132
        }
133
        pass "create philosopher: $i"
134
    } elseif { !$i && $threads_created == 2 } {
135
        # Two threads are created the first time in LinuxThreads,
136
        # where the second is the manager thread.  In NPTL, there is none.
137
        set expect_manager 1
138
        pass "create philosopher: $i"
139
    } else {
140
        fail "create philosopher: $i"
141
    }
142
 
143
    send_gdb "info threads\n"
144
    set threads_after {}
145
    gdb_expect {
146
        -re "info threads\r\n" {
147
            exp_continue
148
        }
149
        -re "^. +(\[0-9\]+ Thread \[-0-9a-fx\]+) \[^\n\]*\n" {
150
            set name $expect_out(1,string)
151
            for {set j 0} {$j != [llength $threads_before] } {incr j} {
152
                if {$name == [lindex $threads_before $j]} {
153
                    set threads_before [lreplace $threads_before $j $j]
154
                    set name ""
155
                    break
156
                }
157
            }
158
            if { $name != "" } {
159
                lappend threads_after $name
160
            }
161
            exp_continue
162
        }
163
        -re "^\[^\n\]*\n" {
164
            verbose -log "skipping line" 2
165
        }
166
        -re "^$gdb_prompt $" {
167
            if { [llength $threads_before] != 0 } {
168
                fail "info threads after: $i"
169
            } elseif { !$i && [llength $threads_after] == 2 } {
170
                set expect_manager 1
171
                pass "info threads after: $i"
172
            } elseif { [llength $threads_after] == 1 } {
173
                if { $expect_manager < 0 } {
174
                    set expect_manager 0
175
                }
176
                pass "info threads after: $i"
177
            } else {
178
                fail "info threads after: $i"
179
            }
180
        }
181
        timeout {
182
            fail "(timeout) info threads after: $i"
183
        }
184
    }
185
 
186
}
187
 
188
set nthreads 6
189
 
190
# Run until there are some threads.
191
gdb_breakpoint [gdb_get_line_number "linuxthreads.exp: info threads 2"]
192
gdb_continue_to_breakpoint "main thread's sleep"
193
set info_threads_ptn ""
194
for {set i $nthreads} {$i > 0} {incr i -1} {
195
    append info_threads_ptn "$i Thread .*"
196
}
197
append info_threads_ptn "\[\r\n\]+$gdb_prompt $"
198
set info_threads_manager_ptn "[expr $nthreads + 1] Thread .*$info_threads_ptn"
199
 
200
gdb_test_multiple "info threads" "info threads 2" {
201
    -re "$info_threads_manager_ptn" {
202
        # We did see a manager thread.  Check that against what we expected.
203
        switch -exact -- $expect_manager {
204
            -1 {
205
                # We weren't sure whether to expect a manager thread.
206
                pass "info threads 2"
207
            }
208
            1 {
209
                # We were expecting a manager thread.
210
                pass "info threads 2"
211
            }
212
 
213
                # We were not expecting to see the manager thread.
214
                fail "info threads 2"
215
            }
216
        }
217
        set expect_manager 1
218
        incr nthreads
219
    }
220
    -re "$info_threads_ptn" {
221
        # We did not see a manager thread.  Check that against what we
222
        # expected.
223
        switch -exact -- $expect_manager {
224
            -1 {
225
                # We weren't sure whether to expect a manager thread.
226
                # Don't expect it from here on out.
227
                pass "info threads 2"
228
            }
229
            1 {
230
                # We were expecting a manager thread, but we didn't see one.
231
                fail "info threads 2"
232
            }
233
 
234
                # We were not expecting to see the manager thread.
235
                pass "info threads 2"
236
            }
237
        }
238
        set expect_manager 0
239
    }
240
}
241
 
242
 
243
# Try setting a thread-specific breakpoint.
244
gdb_breakpoint "print_philosopher thread 5"
245
gdb_continue_to_breakpoint "thread 5's print"
246
# When there is no debugging info available for the thread library,
247
# the backtrace entry for philosopher's caller looks like:
248
#    #1  0x4001c548 in pthread_create () from /lib/libpthread.so.0
249
# If you do have debug info, the output obviously depends more on the
250
# exact library in use; under NPTL, you get:
251
#    #2  0x0012b7fc in start_thread (arg=0x21) at pthread_create.c:264
252
gdb_test "where" "print_philosopher.*philosopher.* \(from .*libpthread\|at pthread_create\).*" \
253
        "first thread-specific breakpoint hit"
254
 
255
# Make sure it's catching the right thread.  Try hitting the
256
# breakpoint ten times, and make sure we don't get anyone else.
257
set only_five 1
258
for {set i 0} {$only_five > 0 && $i < 10} {incr i} {
259
    gdb_continue_to_breakpoint "thread 5's print, pass: $i"
260
    send_gdb "info threads\n"
261
    gdb_expect {
262
        -re "\\* 5 Thread .*  print_philosopher .*\r\n$gdb_prompt $" {
263
            # Okay this time.
264
        }
265
        -re ".*$gdb_prompt $" {
266
            set only_five 0
267
        }
268
        timeout {
269
            set only_five -1
270
        }
271
    }
272
}
273
 
274
set name "thread-specific breakpoint is thread-specific"
275
if {$only_five ==  1} { pass $name }
276
if {$only_five ==  0} { fail $name }
277
if {$only_five == -1} { fail "$name (timeout)" }
278
 
279
 
280
### Select a particular thread.
281
proc select_thread {thread} {
282
    global gdb_prompt
283
 
284
    send_gdb "thread $thread\n"
285
    gdb_expect {
286
        -re "\\\[Switching to thread .*\\\].*\r\n$gdb_prompt $" {
287
            pass "selected thread: $thread"
288
        }
289
        -re "$gdb_prompt $" {
290
            fail "selected thread: $thread"
291
        }
292
        timeout {
293
            fail "selected thread: $thread (timeout)"
294
        }
295
    }
296
}
297
 
298
### Select THREAD, check for a plausible backtrace, and make sure
299
### we're actually selecting a different philosopher each time.
300
### Return true if the thread had a stack which was not only
301
### acceptable, but interesting.  SEEN should be an array in which
302
### SEEN(N) exists iff we have found philosopher number N before.
303
 
304
set main_seen 0
305
set manager_seen 0
306
 
307
proc check_philosopher_stack {thread seen_name} {
308
    global gdb_prompt
309
    upvar $seen_name seen
310
    global main_seen
311
    global expect_manager manager_seen
312
 
313
    set name "philosopher is distinct: $thread"
314
    set interesting 0
315
 
316
    select_thread $thread
317
    send_gdb "where\n"
318
    gdb_expect {
319
        -re ".* in philosopher \\(data=(0x\[0-9a-f\]+).*\r\n$gdb_prompt $" {
320
            set data $expect_out(1,string)
321
            if {[info exists seen($data)]} {
322
                fail $name
323
            } else {
324
                pass $name
325
                set seen($data) yep
326
            }
327
            set interesting 1
328
        }
329
        -re ".* in __pthread_manager \\(.*$gdb_prompt $" {
330
            if {$manager_seen == 1} {
331
                fail "manager thread is distinct: $thread"
332
            } else {
333
                set manager_seen 1
334
                pass "manager thread is distinct: $thread"
335
            }
336
            set interesting 1
337
        }
338
        -re "pthread_start_thread.*\r\n$gdb_prompt $" {
339
            ## Maybe the thread hasn't started yet.
340
            pass $name
341
        }
342
        -re ".* in main \\(.*$gdb_prompt $" {
343
            if {$main_seen == 1} {
344
                fail "main is distinct: $thread"
345
            } else {
346
                set main_seen 1
347
                pass "main is distinct: $thread"
348
            }
349
            set interesting 1
350
        }
351
        -re " in \\?\\?.*\r\n$gdb_prompt $" {
352
            ## Sometimes we can't get a backtrace.  I'm going to call
353
            ## this a pass, since we do verify that at least one
354
            ## thread was interesting, so we can get more consistent
355
            ## test suite totals.  But in my heart, I think it should
356
            ## be an xfail.
357
            pass $name
358
        }
359
        -re "$gdb_prompt $" {
360
            fail $name
361
        }
362
        timeout {
363
            fail "$name (timeout)"
364
        }
365
    }
366
 
367
    return $interesting
368
}
369
 
370
set any_interesting 0
371
array set seen {}
372
unset seen
373
for {set i 1} {$i <= $nthreads} {incr i} {
374
    if [check_philosopher_stack $i seen] {
375
        set any_interesting 1
376
    }
377
}
378
 
379
if {$any_interesting} {
380
    pass "found an interesting thread"
381
} else {
382
    fail "found an interesting thread"
383
}
384
 
385
if {$manager_seen == $expect_manager} {
386
    pass "manager thread found (not found) when expected"
387
} else {
388
    fail "manager thread found (not found) when expected"
389
}

powered by: WebSVN 2.1.0

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