# Copyright 2002-2004, 2007-2012 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 3 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, see <http://www.gnu.org/licenses/>.

# This file was written by Michael Snyder (msnyder@redhat.com)
# This is a test for the gdb command "generate-core-file".


set testfile "gcore"
set srcfile  ${testfile}.c
set binfile  ${objdir}/${subdir}/${testfile}

if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
     untested gcore.exp
     return -1
}

# Start with a fresh gdb.

gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}

# Does this gdb support gcore?
gdb_test_multiple "help gcore" "help gcore" {
    -re "Undefined command: .gcore.*$gdb_prompt $" {
	# gcore command not supported -- nothing to test here.
	unsupported "gdb does not support gcore on this target"
	return -1;
    }
    -re "Save a core file .*$gdb_prompt $" {
	pass "help gcore"
    }
}

if { ! [ runto_main ] } then {
    untested gcore.exp
    return -1
}

proc capture_command_output { command prefix } {
    global gdb_prompt
    global expect_out

    set output_string ""
    gdb_test_multiple "$command" "capture_command_output for $command" {
	-re "${command}\[\r\n\]+${prefix}(.*)\[\r\n\]+$gdb_prompt $" {
	    set output_string $expect_out(1,string)
	}
    }
    return $output_string
}

gdb_test "break terminal_func" "Breakpoint .* at .*${srcfile}, line .*" \
	"set breakpoint at terminal_func"

gdb_test "continue" "Breakpoint .* terminal_func.*" \
	"continue to terminal_func"

set print_prefix ".\[0123456789\]* = "

set pre_corefile_backtrace [capture_command_output "backtrace" ""]
set pre_corefile_regs [capture_command_output "info registers" ""]
set pre_corefile_allregs [capture_command_output "info all-reg" ""]
set pre_corefile_static_array \
	[capture_command_output "print static_array" "$print_prefix"]
set pre_corefile_uninit_array \
	[capture_command_output "print un_initialized_array" "$print_prefix"]
set pre_corefile_heap_string \
	[capture_command_output "print heap_string" "$print_prefix"]
set pre_corefile_local_array \
	[capture_command_output "print array_func::local_array" "$print_prefix"]
set pre_corefile_extern_array \
	[capture_command_output "print extern_array" "$print_prefix"]

set core_supported [gdb_gcore_cmd "${objdir}/${subdir}/gcore.test" \
			"save a corefile"]
if {!$core_supported} {
  return -1
}

# Now restart gdb and load the corefile.
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}

gdb_test_multiple "core ${objdir}/${subdir}/gcore.test" \
    "re-load generated corefile" {
    -re ".* is not a core dump:.*$gdb_prompt $" {
	fail "re-load generated corefile (bad file format)"
	# No use proceeding from here.
	return;	
    }
    -re ".*: No such file or directory.*$gdb_prompt $" {
	fail "re-load generated corefile (file not found)"
	# No use proceeding from here.
	return;	
    }
    -re ".*Couldn't find .* registers in core file.*$gdb_prompt $" {
	fail "re-load generated corefile (incomplete note section)"
    }
    -re "Core was generated by .*$gdb_prompt $" {
	pass "re-load generated corefile"
    }
}

gdb_test_sequence "where" "where in corefile" {
    "\[\r\n\]+#0 .* terminal_func \\(\\) at "
    "\[\r\n\]+#1 .* array_func \\(\\) at "
    "\[\r\n\]+#2 .* factorial_func \\(value=1\\) at "
    "\[\r\n\]+#3 .* factorial_func \\(value=2\\) at "
    "\[\r\n\]+#4 .* factorial_func \\(value=3\\) at "
    "\[\r\n\]+#5 .* factorial_func \\(value=4\\) at "
    "\[\r\n\]+#6 .* factorial_func \\(value=5\\) at "
    "\[\r\n\]+#7 .* factorial_func \\(value=6\\) at "
    "\[\r\n\]+#8 .* main \\(.*\\) at "
}

set post_corefile_regs [capture_command_output "info registers" ""]
if ![string compare $pre_corefile_regs $post_corefile_regs] then {
    pass "corefile restored general registers"
} else {
    fail "corefile restored general registers"
}

set post_corefile_allregs [capture_command_output "info all-reg" ""]
if ![string compare $pre_corefile_allregs $post_corefile_allregs] then {
    pass "corefile restored all registers"
} else {
    fail "corefile restored all registers"
}

set post_corefile_extern_array \
	[capture_command_output "print extern_array" "$print_prefix"]
if ![string compare $pre_corefile_extern_array $post_corefile_extern_array]  {
    pass "corefile restored extern array"
} else {
    fail "corefile restored extern array"
}

set post_corefile_static_array \
	[capture_command_output "print static_array" "$print_prefix"]
if ![string compare $pre_corefile_static_array $post_corefile_static_array]  {
    pass "corefile restored static array"
} else {
    fail "corefile restored static array"
}

set post_corefile_uninit_array \
	[capture_command_output "print un_initialized_array" "$print_prefix"]
if ![string compare $pre_corefile_uninit_array $post_corefile_uninit_array]  {
    pass "corefile restored un-initialized array"
} else {
    fail "corefile restored un-initialized array"
}

set post_corefile_heap_string \
	[capture_command_output "print heap_string" "$print_prefix"]
if ![string compare $pre_corefile_heap_string $post_corefile_heap_string]  {
    pass "corefile restored heap array"
} else {
    fail "corefile restored heap array"
}

set post_corefile_local_array \
	[capture_command_output "print array_func::local_array" "$print_prefix"]
if ![string compare $pre_corefile_local_array $post_corefile_local_array]  {
    pass "corefile restored stack array"
} else {
    fail "corefile restored stack array"
}

set post_corefile_backtrace [capture_command_output "backtrace" ""]
if ![string compare $pre_corefile_backtrace $post_corefile_backtrace]  {
    pass "corefile restored backtrace"
} else {
    fail "corefile restored backtrace"
}
