⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gdb.exp

📁 lwip在ucos上的移植
💻 EXP
📖 第 1 页 / 共 3 页
字号:
# Copyright (C) 1992, 1994, 1995, 1997, 1999 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 Fred Fish. (fnf@cygnus.com)# Generic gdb subroutines that should work for any target.  If these# need to be modified for any target, it can be done with a variable# or by passing arguments.load_lib libgloss.expglobal GDBglobal CHILL_LIBglobal CHILL_RT0if ![info exists CHILL_LIB] {    set CHILL_LIB [findfile $base_dir/../../gcc/ch/runtime/libchill.a "$base_dir/../../gcc/ch/runtime/libchill.a" [transform -lchill]]}verbose "using CHILL_LIB = $CHILL_LIB" 2if ![info exists CHILL_RT0] {    set CHILL_RT0 [findfile $base_dir/../../gcc/ch/runtime/chillrt0.o "$base_dir/../../gcc/ch/runtime/chillrt0.o" ""]}verbose "using CHILL_RT0 = $CHILL_RT0" 2if [info exists TOOL_EXECUTABLE] {    set GDB $TOOL_EXECUTABLE;}if ![info exists GDB] {    if ![is_remote host] {	set GDB [findfile $base_dir/../../gdb/gdb "$base_dir/../../gdb/gdb" [transform gdb]]    } else {	set GDB [transform gdb];    }}verbose "using GDB = $GDB" 2global GDBFLAGSif ![info exists GDBFLAGS] {    set GDBFLAGS "-nx"}verbose "using GDBFLAGS = $GDBFLAGS" 2# The variable gdb_prompt is a regexp which matches the gdb prompt.# Set it if it is not already set.global gdb_promptif ![info exists gdb_prompt] then {    set gdb_prompt "\[(\]gdb\[)\]"}### Only procedures should come after this point.## gdb_version -- extract and print the version number of GDB#proc default_gdb_version {} {    global GDB    global GDBFLAGS    global gdb_prompt    set fileid [open "gdb_cmd" w];    puts $fileid "q";    close $fileid;    set cmdfile [remote_download host "gdb_cmd"];    set output [remote_exec host "$GDB -nw --command $cmdfile"]    remote_file build delete "gdb_cmd";    remote_file host delete "$cmdfile";    set tmp [lindex $output 1];    set version ""    regexp " \[0-9\]\[^ \t\n\r\]+" "$tmp" version    if ![is_remote host] {	clone_output "[which $GDB] version $version $GDBFLAGS\n"    } else {	clone_output "$GDB on remote host version $version $GDBFLAGS\n"    }}proc gdb_version { } {    return [default_gdb_version];}## gdb_unload -- unload a file if one is loaded#proc gdb_unload {} {    global verbose    global GDB    global gdb_prompt    send_gdb "file\n"    gdb_expect 60 {	-re "No executable file now\[^\r\n\]*\[\r\n\]" { exp_continue }	-re "No symbol file now\[^\r\n\]*\[\r\n\]" { exp_continue }	-re "A program is being debugged already..*Kill it.*y or n. $"\	    { send_gdb "y\n"		verbose "\t\tKilling previous program being debugged"	    exp_continue	}	-re "Discard symbol table from .*y or n.*$" {	    send_gdb "y\n"	    exp_continue	}	-re "$gdb_prompt $" {}	timeout {	    perror "couldn't unload file in $GDB (timed out)."	    return -1	}    }}# Many of the tests depend on setting breakpoints at various places and# running until that breakpoint is reached.  At times, we want to start# with a clean-slate with respect to breakpoints, so this utility proc # lets us do this without duplicating this code everywhere.#proc delete_breakpoints {} {    global gdb_prompt    # we need a larger timeout value here or this thing just confuses    # itself.  May need a better implementation if possible. - guo    #    send_gdb "delete breakpoints\n"    gdb_expect 100 {	 -re "Delete all breakpoints.*y or n.*$" {	    send_gdb "y\n";	    exp_continue	}	 -re "$gdb_prompt $" { # This happens if there were no breakpoints	    }	 timeout { perror "Delete all breakpoints in delete_breakpoints (timeout)" ; return }    }    send_gdb "info breakpoints\n"    gdb_expect 100 {	 -re "No breakpoints or watchpoints..*$gdb_prompt $" {}	 -re "$gdb_prompt $" { perror "breakpoints not deleted" ; return }	 -re "Delete all breakpoints.*or n.*$" {	    send_gdb "y\n";	    exp_continue	}	 timeout { perror "info breakpoints (timeout)" ; return }    }}## Generic run command.## The second pattern below matches up to the first newline *only*.# Using ``.*$'' could swallow up output that we attempt to match# elsewhere.#proc gdb_run_cmd {args} {    global gdb_prompt    if [target_info exists gdb_init_command] {	send_gdb "[target_info gdb_init_command]\n";	gdb_expect 30 {	    -re "$gdb_prompt $" { }	    default {		perror "gdb_init_command for target failed";		return;	    }	}    }    if [target_info exists use_gdb_stub] {	if [target_info exists gdb,do_reload_on_run] {	    # Specifying no file, defaults to the executable	    # currently being debugged.	    if { [gdb_load ""] < 0 } {		return;	    }	    send_gdb "continue\n";	    gdb_expect 60 {		-re "Continu\[^\r\n\]*\[\r\n\]" {}		default {}	    }	    return;	}	if [target_info exists gdb,start_symbol] {	    set start [target_info gdb,start_symbol];	} else {	    set start "start";	}	send_gdb  "jump *$start\n"	set start_attempt 1;	while { $start_attempt } {	    # Cap (re)start attempts at three to ensure that this loop	    # always eventually fails.  Don't worry about trying to be	    # clever and not send a command when it has failed.	    if [expr $start_attempt > 3] {		perror "Jump to start() failed (retry count exceeded)";		return;	    }	    set start_attempt [expr $start_attempt + 1];	    gdb_expect 30 {		-re "Continuing at \[^\r\n\]*\[\r\n\]" {		    set start_attempt 0;		}		-re "No symbol \"_start\" in current.*$gdb_prompt $" {		    perror "Can't find start symbol to run in gdb_run";		    return;		}		-re "No symbol \"start\" in current.*$gdb_prompt $" {		    send_gdb "jump *_start\n";		}		-re "No symbol.*context.*$gdb_prompt $" {		    set start_attempt 0;		}		-re "Line.* Jump anyway.*y or n. $" {		    send_gdb "y\n"		}		-re "The program is not being run.*$gdb_prompt $" {		    if { [gdb_load ""] < 0 } {			return;		    }		    send_gdb "jump *$start\n";		}		timeout {		    perror "Jump to start() failed (timeout)"; 		    return		}	    }	}	if [target_info exists gdb_stub] {	    gdb_expect 60 {		-re "$gdb_prompt $" {		    send_gdb "continue\n"		}	    }	}	return    }    send_gdb "run $args\n"# This doesn't work quite right yet.    gdb_expect 60 {	-re "The program .* has been started already.*y or n. $" {	    send_gdb "y\n"	    exp_continue	}	-re "Starting program: \[^\r\n\]*" {}    }}proc gdb_breakpoint { function } {    global gdb_prompt    global decimal    send_gdb "break $function\n"    # The first two regexps are what we get with -g, the third is without -g.    gdb_expect 30 {	-re "Breakpoint \[0-9\]* at .*: file .*, line $decimal.\r\n$gdb_prompt $" {}	-re "Breakpoint \[0-9\]*: file .*, line $decimal.\r\n$gdb_prompt $" {}	-re "Breakpoint \[0-9\]* at .*$gdb_prompt $" {}	-re "$gdb_prompt $" { fail "setting breakpoint at $function" ; return 0 }	timeout { fail "setting breakpoint at $function (timeout)" ; return 0 }    }    return 1;}    # Set breakpoint at function and run gdb until it breaks there.# Since this is the only breakpoint that will be set, if it stops# at a breakpoint, we will assume it is the one we want.  We can't# just compare to "function" because it might be a fully qualified,# single quoted C++ function specifier.proc runto { function } {    global gdb_prompt    global decimal    delete_breakpoints    if ![gdb_breakpoint $function] {	return 0;    }    gdb_run_cmd        # the "at foo.c:36" output we get with -g.    # the "in func" output we get without -g.    gdb_expect 30 {	-re "Break.* at .*:$decimal.*$gdb_prompt $" {	    return 1	}	-re "Breakpoint \[0-9\]*, \[0-9xa-f\]* in .*$gdb_prompt $" { 	    return 1	}	-re "$gdb_prompt $" { 	    fail "running to $function in runto"	    return 0	}	timeout { 	    fail "running to $function in runto (timeout)"	    return 0	}    }    return 1}## runto_main -- ask gdb to run until we hit a breakpoint at main.#		The case where the target uses stubs has to be handled#		specially--if it uses stubs, assuming we hit#		breakpoint() and just step out of the function.#proc runto_main { } {    global gdb_prompt    global decimal    if ![target_info exists gdb_stub] {	return [runto main]    }			    delete_breakpoints    gdb_step_for_stub;    return 1}### Continue, and expect to hit a breakpoint.### Report a pass or fail, depending on whether it seems to have### worked.  Use NAME as part of the test name; each call to### continue_to_breakpoint should use a NAME which is unique within### that test file.proc gdb_continue_to_breakpoint {name} {    global gdb_prompt    set full_name "continue to breakpoint: $name"    send_gdb "continue\n"    gdb_expect {	-re "Breakpoint .* at .*\r\n$gdb_prompt $" {	    pass $full_name	}	-re ".*$gdb_prompt $" {	    fail $full_name	}	timeout { 	    fail "$full_name (timeout)"	}    }}# gdb_test COMMAND PATTERN MESSAGE -- send a command to gdb; test the result.## COMMAND is the command to execute, send to GDB with send_gdb.  If#   this is the null string no command is sent.# PATTERN is the pattern to match for a PASS, and must NOT include#   the \r\n sequence immediately before the gdb prompt.# MESSAGE is an optional message to be printed.  If this is#   omitted, then the pass/fail messages use the command string as the#   message.  (If this is the empty string, then sometimes we don't#   call pass or fail at all; I don't understand this at all.)## Returns:#    1 if the test failed,#    0 if the test passes,#   -1 if there was an internal error.#  proc gdb_test { args } {    global verbose    global gdb_prompt    global GDB    upvar timeout timeout    if [llength $args]>2 then {	set message [lindex $args 2]    } else {	set message [lindex $args 0]    }    set command [lindex $args 0]    set pattern [lindex $args 1]    if [llength $args]==5 {	set question_string [lindex $args 3];	set response_string [lindex $args 4];    } else {	set question_string "^FOOBAR$"    }    if $verbose>2 then {	send_user "Sending \"$command\" to gdb\n"	send_user "Looking to match \"$pattern\"\n"	send_user "Message is \"$message\"\n"    }    set result -1    set string "${command}\n";    if { $command != "" } {	while { "$string" != "" } {	    set foo [string first "\n" "$string"];	    set len [string length "$string"];	    if { $foo < [expr $len - 1] } {		set str [string range "$string" 0 $foo];		if { [send_gdb "$str"] != "" } {		    global suppress_flag;		    if { ! $suppress_flag } {			perror "Couldn't send $command to GDB.";		    }		    fail "$message";		    return $result;		}		# since we're checking if each line of the multi-line		# command are 'accepted' by GDB here,		# we need to set -notransfer expect option so that		# command output is not lost for pattern matching		# - guo		gdb_expect -notransfer 2 {		    -re "\[\r\n\]" { }		    timeout { }		}		set string [string range "$string" [expr $foo + 1] end];	    } else {		break;	    }	}	if { "$string" != "" } {	    if { [send_gdb "$string"] != "" } {		global suppress_flag;		if { ! $suppress_flag } {		    perror "Couldn't send $command to GDB.";		}		fail "$message";		return $result;	    }	}    }    if [info exists timeout] {	set tmt $timeout;    } else {	global timeout;	if [info exists timeout] {	    set tmt $timeout;	} else {	    set tmt 60;	}    }    gdb_expect $tmt {	 -re "\\*\\*\\* DOSEXIT code.*" {	     if { $message != "" } {		 fail "$message";	     }	     gdb_suppress_entire_file "GDB died";	     return -1;	 }	 -re "Ending remote debugging.*$gdb_prompt $" {	    if ![isnative] then {		warning "Can`t communicate to remote target."	    }	    gdb_exit	    gdb_start	    set result -1	}	 -re "\[\r\n\]*($pattern)\[\r\n\]+$gdb_prompt $" {	    if ![string match "" $message] then {		pass "$message"	    }	    set result 0	}	 -re "(${question_string})$" {	    send_gdb "$response_string\n";	    exp_continue;	}	 -re "Undefined\[a-z\]* command:.*$gdb_prompt $" {	    perror "Undefined command \"$command\"."            fail "$message"	    set result 1	}	 -re "Ambiguous command.*$gdb_prompt $" {	    perror "\"$command\" is not a unique command name."            fail "$message"	    set result 1	}	 -re "Program exited with code \[0-9\]+.*$gdb_prompt $" {	    if ![string match "" $message] then {		set errmsg "$message: the program exited"	    } else {		set errmsg "$command: the program exited"	    }	    fail "$errmsg"	    return -1	}	 -re "The program is not being run.*$gdb_prompt $" {	    if ![string match "" $message] then {		set errmsg "$message: the program is no longer running"	    } else {		set errmsg "$command: the program is no longer running"	    }	    fail "$errmsg"	    return -1	}	 -re ".*$gdb_prompt $" {	    if ![string match "" $message] then {		fail "$message"	    }	    set result 1	}	 "<return>" {	    send_gdb "\n"	    perror "Window too small."            fail "$message"	}	 -re "\\(y or n\\) " {	    send_gdb "n\n"	    perror "Got interactive prompt."            fail "$message"	}	 eof {	     perror "Process no longer exists"	     if { $message != "" } {		 fail "$message"	     }	     return -1	}	 full_buffer {	    perror "internal buffer is full."            fail "$message"	}	timeout	{	    if ![string match "" $message] then {		fail "$message (timeout)"	    }	    set result 1	}    }    return $result}# Test that a command gives an error.  For pass or fail, return# a 1 to indicate that more tests can proceed.  However a timeout# is a serious error, generates a special fail message, and causes# a 0 to be returned to indicate that more tests are likely to fail# as well.proc test_print_reject { args } {    global gdb_prompt    global verbose    if [llength $args]==2 then {	set expectthis [lindex $args 1]    } else {	set expectthis "should never match this bogus string"

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -