# Copyright 2002-2013 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"
}
