# Copyright 2002
# 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 Jason Molenda (jmolenda@apple.com)

if $tracelevel then {
        strace $tracelevel
}


# Test inferior function calls that stop for some reason - either because
# of a gdb breakpoint, or because the function does something invalid.

set timeout 30

set prms_id 0
set bug_id 0

# APPLE LOCAL jmolenda
# r. 3096429 -data-evaluate-expression stomps on unwindonsignal setting
set r3096429 "(r. 3096429)"

load_lib mi-support.exp
set MIFLAGS "-i=mi1"

set testfile "inf-call-interrupt"
set binfile ${objdir}/${subdir}/${testfile}
set srcfile ${srcdir}/${subdir}/${testfile}.c

if  { [gdb_compile "${srcfile}" "${binfile}" executable {debug}] != "" } {
     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}


###
### First set of tests:  Not setting unwindonsignal, console mode
###

# Start with a fresh gdb
gdb_exit

gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load $binfile
if ![runto_main] then { 
  fail "inf-call-interrupt tests suppressed"
  return -1
}
gdb_test "break foo" "Breakpoint 2.*inf-call-interrupt.c.*"

gdb_test "call foo()" "The program being debugged stopped while in a function called from.*"
gdb_test "bt" "#0 *foo.*#1 *<function called from gdb>\[\r\n\]+#2 *main.*" "backtrace while stopped at bp in inf func call"
gdb_test "cont" "Continuing.\[\r\n\]+hi in foo" "continue out of inferior function call"
gdb_test "fr 0" "#0 *main .*"

gdb_test "call bar()" ".*The program being debugged was signaled while in a function called from GDB.*"
gdb_test "bt" "#0 *($hex)? in bar.*#1 *<function called from gdb>\[\r\n\]+#2 *main.*" "backtrace while stopped at seg fault in inferior function call"

gdb_exit



###
### Second set of tests:  Setting unwindonsignal, console mode
###

gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load $binfile
if ![runto_main] then { 
  fail "inf-call-interrupt tests suppressed"
  return -1
}
gdb_test "break foo" "Breakpoint 2.*inf-call-interrupt.c.*"
gdb_test "set unwindonsignal on" ""

gdb_test "call foo()" "The program being debugged stopped while in a function called from.*" "call foo() with unwindonsignal"
gdb_test "bt" "#0 *foo.*#1 *<function called from gdb>\[\r\n\]+#2 *main.*" "backtrace while stopped at bp in inf func call with unwindonsignal"
gdb_test "cont" "Continuing.\[\r\n\]+hi in foo" "continue out of inferior function call with unwindonsignal"
gdb_test "fr 0" "#0 *main .*" "back at main with unwindonsignal"

gdb_test "call bar()" ".*The program being debugged was signaled while in a function called from GDB.\[\r\n\]+GDB has restored the context to what it was before the call.\[\r\n\]+To change this behavior use \"set unwindonsignal off\"\[\r\n\]+Evaluation of the expression containing the function \\(bar\\) will be abandoned."
gdb_test "fr 0" "#0 *main .*" "back at main after catching segfault in inf func call with unwindonsignal"
gdb_exit




###
### Third set of tests:  Not setting unwindonsignal, mi1 mode
###

if [mi_gdb_start] {
    continue
}
mi_delete_breakpoints
mi_gdb_reinitialize_dir $srcdir/$subdir
mi_gdb_load ${binfile}
mi_run_to_main

mi_gdb_test "400-break-insert foo" "400\\^done,bkpt=\{number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"foo\",file=\".*inf-call-interrupt.c\",line=\"$decimal\",times=\"0\"\}"
mi_gdb_test "401-data-evaluate-expression foo()" "401\\^error,msg=\"The program being debugged stopped while in a function called from GDB.*\",reason=\"breakpoint-hit\",commands=\"no\",bkptno=\"2\",thread-id=\"1\"" "MI call inferior's function with a breakpoint set in it"

mi_gdb_test "402-stack-list-frames" "402\\^done,stack=\\\[frame=\{level=\"0\",addr=\"$hex\",fp=\"$hex\",func=\"foo\",file=\".*inf-call-interrupt.c\",line=\"$decimal\",dir=\".*\"\},frame=\{level=\"1\",addr=\"$hex\",fp=\"$hex\",func=\"<function called from gdb>\"\},frame=\{level=\"2\",addr=\"$hex\",fp=\"$hex\",func=\"main\",file=\".*inf-call-interrupt.c\",line=\"$decimal\",dir=\".*\"\}.*\\\]" "MI backtrace from inferior function stopped at bp, showing gdb dummy frame"

mi_gdb_test "403-exec-continue" "403\\^running\[\r\n\]+$mi_gdb_prompt\[\r\n\]+hi in foo\[\r\n\]+403\\\*stopped"
mi_gdb_test "404-stack-list-frames 0 0" "404\\^done,stack=\\\[frame=\{level=\"0\",addr=\"$hex\",fp=\"$hex\",func=\"main\",file=\".*inf-call-interrupt.c\",line=\"$decimal\",dir=\".*\"\}.*\\\]"

mi_gdb_test "405-data-evaluate-expression -u bar()" ".*405\\^error,msg=\"The program being debugged was signaled while in a function called from GDB.\\\\nGDB has restored the context to what it was before the call.\\\\nTo change this behavior use \\\\\"set unwindonsignal off\\\\\"\\\\nEvaluation of the expression containing the function \\(bar\\) will be abandoned.\",reason=\"signal-received\",signal-name=\".*\",signal-meaning=\".*\",thread-id=\"1\".*"

mi_gdb_test "406-stack-list-frames" "406\\^done,stack=\\\[frame=\{level=\"0\",addr=\"$hex\",fp=\"$hex\",func=\"main\",file=\".*inf-call-interrupt.c\",line=\"$decimal\",dir=\".*\"\}.*\\\]"

mi_gdb_test "407-data-evaluate-expression bar()" ".*407\\^error,msg=\"The program being debugged was signaled while in a function called from GDB.\\\\nGDB remains in the frame where the signal was received.\\\\nTo change this behavior use \\\\\"set unwindonsignal on\\\\\"\\\\nEvaluation of the expression containing the function \\(bar\\) will be abandoned.\",reason=\"signal-received\",signal-name=\".*\",signal-meaning=\".*\",thread-id=\"1\".*" "MI get exception while calling inferior function"

mi_gdb_test "408-stack-list-frames" "408\\^done,stack=\\\[frame=\{level=\"0\",addr=\"$hex\",fp=\"$hex\",func=\"bar\",file=\".*inf-call-interrupt.c\",line=\"$decimal\",dir=\".*\"\},frame=\{level=\"1\",addr=\"$hex\",fp=\"$hex\",func=\"<function called from gdb>\"\},frame=\{level=\"2\",addr=\"$hex\",fp=\"$hex\",func=\"main\",file=\".*inf-call-interrupt.c\",line=\"$decimal\",dir=\".*\"\}.*\\\]" "MI backtrace from inferior function at exception, showing gdb dummy frame"

mi_gdb_exit



###
### Fourth set of tests:  Setting unwindonsignal, mi1 mode
###




if [mi_gdb_start] {
    continue
}
mi_delete_breakpoints
mi_gdb_reinitialize_dir $srcdir/$subdir
mi_gdb_load ${binfile}
mi_run_to_main

mi_gdb_test "1397-gdb-show unwindonsignal" "1397\\^done,value=\"off\"" "check unwindonsignal at startup"
mi_gdb_test "1398-gdb-set unwindonsignal 1" "1398\\^done" "set unwindonsignal"
mi_gdb_test "1399-gdb-show unwindonsignal" "1399\\^done,value=\"on\"" "verify that unwindonsignal was set"

mi_gdb_test "1400-break-insert foo" "1400\\^done,bkpt=\{number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"foo\",file=\".*inf-call-interrupt.c\",line=\"$decimal\",times=\"0\"\}" 
mi_gdb_test "1401-data-evaluate-expression foo()" "1401\\^error,msg=\"The program being debugged stopped while in a function called from GDB.*\",reason=\"breakpoint-hit\",commands=\"no\",bkptno=\"2\",thread-id=\"1\""

mi_gdb_test "1402-stack-list-frames" "1402\\^done,stack=\\\[frame=\{level=\"0\",addr=\"$hex\",fp=\"$hex\",func=\"foo\",file=\".*inf-call-interrupt.c\",line=\"$decimal\",dir=\".*\"\},frame=\{level=\"1\",addr=\"$hex\",fp=\"$hex\",func=\"<function called from gdb>\"\},frame=\{level=\"2\",addr=\"$hex\",fp=\"$hex\",func=\"main\",file=\".*inf-call-interrupt.c\",line=\"$decimal\",dir=\".*\"\}.*\\\]"

mi_gdb_test "1403-exec-continue" "1403\\^running\[\r\n\]+$mi_gdb_prompt\[\r\n\]+hi in foo\[\r\n\]+1403\\\*stopped"
mi_gdb_test "1404-stack-list-frames 0 0" "1404\\^done,stack=\\\[frame=\{level=\"0\",addr=\"$hex\",fp=\"$hex\",func=\"main\",file=\".*inf-call-interrupt.c\",line=\"$decimal\",dir=\".*\"\}.*\\\]"

mi_gdb_test "1405-data-evaluate-expression bar()" ".*1405\\^error,msg=\"The program being debugged was signaled while in a function called from GDB.\\\\nGDB has restored the context to what it was before the call.\\\\nTo change this behavior use \\\\\"set unwindonsignal off\\\\\"\\\\nEvaluation of the expression containing the function \\(bar\\) will be abandoned.\",reason=\"signal-received\",signal-name=\".*\",signal-meaning=\".*\",thread-id=\"1\".*" "MI evaluate bar() with unwindonsignal set $r3096429"

mi_gdb_test "1406-stack-list-frames" "1406\\^done,stack=\\\[frame=\{level=\"0\",addr=\"$hex\",fp=\"$hex\",func=\"main\",file=\".*inf-call-interrupt.c\",line=\"$decimal\",dir=\".*\"\}.*\\\]" "MI verify back at main after calling bar with unwindonsignal set $r3096429"

mi_gdb_test "1407-data-evaluate-expression -u bar()" ".*1407\\^error,msg=\"The program being debugged was signaled while in a function called from GDB.\\\\nGDB has restored the context to what it was before the call.\\\\nTo change this behavior use \\\\\"set unwindonsignal off\\\\\"\\\\nEvaluation of the expression containing the function \\(bar\\) will be abandoned.\",reason=\"signal-received\",signal-name=\".*\",signal-meaning=\".*\",thread-id=\"1\".*"

mi_gdb_test "1408-stack-list-frames" "1408\\^done,stack=\\\[frame=\{level=\"0\",addr=\"$hex\",fp=\"$hex\",func=\"main\",file=\".*inf-call-interrupt.c\",line=\"$decimal\",dir=\".*\"\}.*\\\]" "MI verify back at main after calling bar with data-evaluate-expression -u $r3096429"

mi_gdb_exit


return 0
