| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 
 | #   Copyright (C) 1988, 1990, 1991, 1992, 1994, 1997 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
# Please email any bugs, comments, and/or additions to this file to:
# bug-gdb@prep.ai.mit.edu
# This file was written by Rob Savoye. (rob@cygnus.com)
if $tracelevel then {
    strace $tracelevel
}
set prms_id 0
set bug_id 0
# are we on a target board
if [is_remote target] {
    return
}
if [istarget "m68k*-*-hpux*"] then {
    # The top-level makefile passes CFLAGS= (no -g) for hp300.  This probably
    # should be fixed (it is only needed for gcc bootstrapping, not gdb),
    # but until then.....
    setup_xfail "*-*-*"
    fail "cannot test self if compiled without debug info"
    return -1
}
# Not all of the lines of code near the start of main are executed for
# every machine.  Also, optimization may reorder some of the lines.
# So all we do is try to step or next over everything until we get
# to a line that we know is always executed.
proc do_steps_and_nexts {} {
    global gdb_prompt
    global srcdir
 
    gdb_reinitialize_dir $srcdir/..
    for {set count 0} {$count < 22} {incr count} {
	send_gdb "list\n"
	gdb_expect {
	    -re ".*context = data.*$gdb_prompt $" {
		set description "step over context initialization"
		set command "step"
	    }
	    -re ".*argc = context->argc.*$gdb_prompt $" {
		set description "step over argc initialization"
		set command "step"
	    }
	    -re ".*argv = context->argv.*$gdb_prompt $" {
		set description "step over argv initialization"
		set command "step"
	    }
	    -re ".*quiet = 0.*$gdb_prompt $" {
		set description "step over quiet initialization"
		set command "step"
	    }
	    -re ".*batch = 0.*$gdb_prompt $" {
		set description "step over batch initialization"
		set command "step"
	    }
	    -re ".*symarg = NULL.*$gdb_prompt $" {
		set description "step over symarg initialization"
		set command "step"
	    }
	    -re ".*execarg = NULL.*$gdb_prompt $" {
		set description "step over execarg initialization"
		set command "step"
	    }
	    -re ".*corearg = NULL.*$gdb_prompt $" {
		set description "step over corearg initialization"
		set command "step"
	    }
	    -re ".*cdarg = NULL.*$gdb_prompt $" {
		set description "step over cdarg initialization"
		set command "step"
	    }
	    -re ".*ttyarg = NULL.*$gdb_prompt $" {
		set description "step over ttyarg initialization"
		set command "step"
	    }
	    -re ".*time_at_startup = get_run_time.*$gdb_prompt $" {
		set description "next over get_run_time and everything it calls"
		set command "next"
	    }
	    -re ".*START_PROGRESS.*$gdb_prompt $" {
		set description "next over START_PROGRESS and everything it calls"
		set command "next"
	    }
	    -re ".*mac_init.*$gdb_prompt $" {
		set description "next over mac_init and everything it calls"
		set command "next"
	    }
	    -re ".*init_malloc.*$gdb_prompt $" {
		set description "next over init_malloc and everything it calls"
		set command "next"
	    }
	    -re ".*count . 0x3.*$gdb_prompt $" {
		set description "next over conditional stack alignment code 1"
		set command "next"
	    }
	    -re ".*if .i != 0.*$gdb_prompt $" {
		set description "next over conditional stack alignment code 2"
		set command "next"
	    }
	    -re ".*alloca .i - 4.*$gdb_prompt $" {
		set description "next over conditional stack alignment alloca"
		set command "next"
	    }
	    -re ".*cmdsize = 1.*$gdb_prompt $" {
		set description "step over cmdsize initialization"
		set command "next"
	    }
	    -re ".*cmdarg = .* xmalloc.*$gdb_prompt $" {
		set description "next over cmdarg initialization via xmalloc"
		set command "next"
	    }
	    -re ".*ncmd = 0.*$gdb_prompt $" {
		set description "next over ncmd initialization"
		set command "next"
	    }
	    -re ".*dirsize = 1.*$gdb_prompt $" {
		set description "next over dirsize initialization"
		set command "next"
	    }
	    -re ".*dirarg = .* xmalloc.*$gdb_prompt $" {
		return
	    }
	    -re "\[ \t\]+\{\r\n$gdb_prompt $" {
		setup_xfail "mips-*-irix5*"
		fail "$description ended up at odd location"
	    }
	    -re ".*main.c.*No such file or directory.*$gdb_prompt $" {
		setup_xfail "rs6000-*-aix3*"
		fail "must be able to list source lines"
		return
	    }
	    -re ".*$gdb_prompt $" {
		fail "unknown source line after $description"
		return
	    }
	    default {
		fail "unknown source line near main"
		return
	    }
	}
	send_gdb "$command\n"
	gdb_expect {
	    -re ".*No such file or directory.\r\n$gdb_prompt $" {
		fail "$description (no source available)"
	    }
	    -re ".*A file or directory .* does not exist..\r\n$gdb_prompt $" {
		fail "$description (no source available)"
	    }
	    -re ".*$gdb_prompt $" {
		pass "$description"
	    }
	    timeout {
		fail "$description (timeout)"
	    }
	}
    }
}
proc test_with_self { executable } {
    global gdb_prompt
    global tool
    global det_file
    global decimal
    global timeout
    # load yourself into the debugger
    # This can take a relatively long time, particularly for testing where
    # the executable is being accessed over a network, or where gdb does not
    # support partial symbols for a particular target and has to load the
    # entire symbol table.  Set the timeout to 10 minutes, which should be
    # adequate for most environments (it *has* timed out with 5 min on a
    # SPARCstation SLC under moderate load, so this isn't unreasonable).
    # After gdb is started, set the timeout to 30 seconds for the duration
    # of this test, and then back to the original value.
    set oldtimeout $timeout
    set timeout 600
    verbose "Timeout is now $timeout seconds" 2
    if {[gdb_load $executable] <0} then {
	set timeout $oldtimeout
	verbose "Timeout is now $timeout seconds" 2
	return -1
    }
    set timeout $oldtimeout
    verbose "Timeout is now $timeout seconds" 2
    # disassemble yourself
    gdb_test "x/10i main" \
	    "x/10i.*main.*main.$decimal.*main.$decimal.*" \
	    "Disassemble main"
    # Set a breakpoint at main
    gdb_test "break captured_main" \
	    "Breakpoint.*at.* file.*, line.*" \
	    "breakpoint in captured_main"
    # We'll need this when we send a ^C to GDB.  Need to do it before we
    # run the program and gdb starts saving and restoring tty states.
    # On Ultrix, we don't need it and it is really slow (because shell_escape
    # doesn't use vfork).
    if ![istarget "*-*-ultrix*"] then {
	gdb_test "shell stty intr '^C'" "" \
	    "set interrupt character in test_with_self"
    }
    # FIXME: If we put this after the run to main, the first list
    # command doesn't print the same line as the current line where
    # gdb is stopped.
    gdb_test "set listsize 1" "" "set listsize to 1"
    # run yourself
    # It may take a very long time for the inferior gdb to start (lynx),
    # so we bump it back up for the duration of this command.
    set timeout 600
    set description "run until breakpoint at captured_main"
    send_gdb "run -nw\n"
    gdb_expect {
	-re "Starting program.*Breakpoint \[0-9\]+,.*captured_main .data.* at .*main.c:.*$gdb_prompt $" {
	    pass "$description"
	}
	-re "Starting program.*Breakpoint \[0-9\]+,.*captured_main .data.*$gdb_prompt $" {
	    xfail "$description (line numbers scrambled?)"
	}
	-re "vfork: No more processes.*$gdb_prompt $" {
	    fail "$description (out of virtual memory)"
	    set timeout $oldtimeout
	    verbose "Timeout is now $timeout seconds" 2
	    return -1
	}
	-re ".*$gdb_prompt $" {
	    fail "$description"
	    set timeout $oldtimeout
	    verbose "Timeout is now $timeout seconds" 2
	    return -1
	}
	timeout {
	    fail "$description (timeout)"
	}
    }
    set timeout $oldtimeout
    verbose "Timeout is now $timeout seconds" 2
    # do we have a version number ?
    send_gdb "print version\n"
    gdb_expect {
	-re ".\[0-9\]+ = .\[0-9.\]+.*$gdb_prompt $" {
	    pass "printed version as string"
	}
	-re ".\[0-9\]+ = +0x.*\[0-9.\]+.*$gdb_prompt $" {
	    pass "printed version as pointer"
	}
	-re ".\[0-9\]+ = +.+ +0x.*\[0-9.\]+.*$gdb_prompt $" {
	    pass "printed version with cast"
	}
	-re ".*$gdb_prompt $"	{ fail "printed version" }
	timeout		{ fail "(timeout) printed version" }
    }
    do_steps_and_nexts
    gdb_test "print \"foo\"" ".\[0-9\]+ = \"foo\"" "print a string"
    # do_steps_and_nexts left us ready to execute an xmalloc call,
    # so give that a try.
    # If we don't actually enter the xmalloc call when we give a
    # step command that seems like a genuine bug.  It seems to happen
    # on most RISC processors.
    setup_xfail "alpha-*-*" "mips-*-*"
    set description "step into xmalloc call"
    send_gdb "step\n"
    gdb_expect {
	-re "xmalloc.*size=.*at.*utils.c.*$gdb_prompt $" {
	    pass "$description"
	}
	-re ".*No such file or directory.\r\n$gdb_prompt $" {
	    pass "$description (no source available)"
	}
	-re "A file or directory .* does not exist..\r\n$gdb_prompt $" {
	    pass "$description (no source available)"
	}
	-re ".*$gdb_prompt $" {
	    fail "$description"
	}
	timeout {
	    fail "$description (timeout)"
	}
    }
    # start the "xgdb" process
    send_gdb "continue\n"
    gdb_expect {
	-re "GNU gdb \[0-9\.\]*.*
Copyright \[0-9\]* Free Software Foundation, Inc.*
GDB is free software, covered by the GNU General Public License, and you are.*
welcome to change it and/or distribute copies of it under certain conditions.*
Type \"show copying\" to see the conditions.*
There is absolutely no warranty for GDB.  Type \"show warranty\" for details.*
This GDB was configured as .*$gdb_prompt $"\
	    { pass "xgdb is at prompt" }
	-re "GDB is free software and you are welcome to distribute copies of it.*
 under certain conditions; type \"show copying\" to see the conditions..*
There is absolutely no warranty for GDB; type \"show warranty\" for details..*
GDB.*Copyright \[0-9\]+ Free Software Foundation, Inc..*$gdb_prompt $"\
	    { pass "xgdb is at prompt (obsolescent gdb)" }
	-re ".*$gdb_prompt $"       { fail "xgdb is at prompt" }
	timeout	            { fail "(timeout) xgdb is at prompt" }
    }
    
    # set xgdb prompt so we can tell which is which
    send_gdb "set prompt (xgdb) \n"
    gdb_expect {
	-re "\[(\]xgdb\[)\].*\[(\]xgdb\[)\] $"	{ pass "Set xgdb prompt" }
	-re ".*$gdb_prompt $"		{ fail "Set xgdb prompt" }
	default				{ fail "(timeout) Set xgdb prompt" }
    }
    
    # kill the xgdb process
    set description "send ^C to child process"
    send_gdb "\003"
    gdb_expect {
	-re "Program received signal SIGINT.*$gdb_prompt $" {
	    pass "$description"
	}
	-re ".*$gdb_prompt $" {
	    fail "$description"
	}
	timeout {
	    fail "$description (timeout)"
	}
    }
    
    set description "send SIGINT signal to child process"
    send_gdb "signal SIGINT\n"
    gdb_expect {
	-re "Continuing with signal SIGINT.*$gdb_prompt $" {
	    pass "$description"
	}
	-re ".*$gdb_prompt $" {
	    fail "$description"
	}
	timeout {
	    fail "$description (timeout)"
	}
    }
    
    # get a stack trace
    #
    # This fails on some linux systems for unknown reasons.  On the
    # systems where it fails, sometimes it works fine when run manually.
    # The testsuite failures may not be limited to just aout systems.
    setup_xfail "i*86-pc-linuxaout-gnu" "hppa*-*-hpux*"
    set description "backtrace through signal handler"
    send_gdb "backtrace\n"
    gdb_expect {
	-re "#0.*read.*in main \\(.*\\) at .*main\\.c.*$gdb_prompt $" {
	    pass "$description"
	}
	-re ".*$gdb_prompt $" {
	    # On the alpha, we hit the infamous problem about gdb
	    # being unable to get the frame pointer (mentioned in
	    # gdb/README).  As it is intermittent, there is no way to
	    # XFAIL it which will give us an XPASS if the problem goes
	    # away.
	    setup_xfail "alpha*-*-osf*"
	    fail "$description"
	}
	timeout {
	    fail "$description (timeout)"
	}
    }
    # Set the timeout back to the value it had when we were called.
    set timeout $oldtimeout
    verbose "Timeout is now $timeout seconds" 2
    # Restart gdb in case next test expects it to be started already.
    return 0
}
# Find a pathname to a file that we would execute if the shell was asked
# to run $arg using the current PATH.
proc find_gdb { arg } {
    # If the arg directly specifies an existing executable file, then
    # simply use it.
    if [file executable $arg] then {
	return $arg
    }
    set result [which $arg]
    if [string match "/" [ string range $result 0 0 ]] then {
	return $result
    }
    # If everything fails, just return the unqualified pathname as default
    # and hope for best.
    return $arg
}
# Run the test with self.
# Copy the file executable file in case this OS doesn't like to edit its own
# text space.
set GDB_FULLPATH [find_gdb $GDB]
# Remove any old copy lying around.
remote_file host delete x$tool
gdb_start
set file [remote_download host $GDB_FULLPATH x$tool]
set result [test_with_self $file];
gdb_exit;
catch "remote_file host delete $file";
if {$result <0} then {
    warning "Couldn't test self"
    return -1
}
 |