# Copyright 2002, 2003, 2004, 2007, 2008, 2009 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".

if $tracelevel then {
	strace $tracelevel
}

set prms_id 0
set bug_id 0

# Single-threaded test case
set testfile "pthreads"
set srcfile  ${testfile}.c
set binfile  ${objdir}/${subdir}/gcore-${testfile}

if [istarget "*-*-linux"] then {
    set target_cflags "-D_MIT_POSIX_THREADS"
} else {
    set target_cflags ""
}

if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
    return -1
}

# Now we can proceed with the real testing.

# Start with a fresh gdb.

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

# regexp for "horizontal" text (i.e. doesn't include newline or
# carriage return)
set horiz "\[^\n\r\]*"

# regexp for newline
set nl "\[\r\n\]+"

set timeout 30

send_gdb "help gcore\n"
gdb_expect {
    -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"
    }
    -re ".*$gdb_prompt $" {
	fail "help gcore"
    }
    timeout {
	fail "help gcore (timeout)"
    }
}

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

send_gdb "info threads\n"
gdb_expect {
    -re ".* main .*$gdb_prompt $" {
	# OK, threads are supported.
    }
    -re "${nl}$gdb_prompt $" {
	unsupported "gdb does not support threads on this target"
	return -1;
    }
}

# Make sure thread 1 is running
delete_breakpoints
gdb_breakpoint "thread1"
gdb_test "continue" "Continuing.*Breakpoint.* thread1 .*" "thread 1 is running"

# Make sure thread 2 is running
delete_breakpoints
gdb_breakpoint "thread2"
gdb_test "continue" "Continuing.*Breakpoint.* thread2 .*" "thread 2 is running"

set escapedfilename [string_to_regexp ${objdir}/${subdir}/gcore.test]
# Drop corefile
gdb_test_multiple "gcore ${objdir}/${subdir}/gcore.test" \
	"save a corefile" \
{
  -re "Saved corefile ${escapedfilename}\[\r\n\]+$gdb_prompt $" {
    pass "save a corefile"
    global core_supported
    set core_supported 1
  }
  -re "Can't create a corefile\[\r\n\]+$gdb_prompt $" {
    unsupported "save a corefile"
    global core_supported
    set core_supported 0
  }
}

global core_supported
if {!$core_supported} {
  return -1
}

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

send_gdb "core ${objdir}/${subdir}/gcore.test\n"
gdb_expect {
    -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"
    }
    -re ".*$gdb_prompt $" {
	fail "re-load generated corefile"
    }
    timeout {
	fail "re-load generated corefile (timeout)"
    }
}

# FIXME: now what can we test about the thread state?
# We do not know for certain that there should be at least 
# three threads, because who knows what kind of many-to-one
# mapping various OS's may do?  Let's assume that there must
# be at least two threads:

gdb_test "info threads" ".*${nl}  2 ${horiz}${nl}\\* 1 .*" \
	"corefile contains at least two threads"

# One thread in the corefile should be in the "thread2" function.

gdb_test "info threads" ".* thread2 .*" \
	"a corefile thread is executing thread2"

# The thread2 thread should be marked as the current thread.

gdb_test "info threads" ".*${nl}\\* ${horiz} thread2 .*" \
	"thread2 is current thread in corefile"

