# 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".

# Single-threaded test case
standard_testfile pthreads.c
set objfile  $binfile.o
set corefile $binfile.test
set core0file ${binfile}0.test

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

# Attempt to prevent -Wl,-z,relro which happens by default at least on
# Kubuntu-10.10.  Due to PR corefiles/11804 will then GDB be unable to find
# libpthread, therefore libthread_db will not fail as expected
# on the test `zeroed-threads cannot be listed'.

set opts [list debug]
if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${objfile}" object $opts] != ""
    || ([gdb_compile_pthreads "${objfile}" "${binfile}" executable [concat $opts {additional_flags=-Wl,-z,norelro}] ] != ""
        && [gdb_compile_pthreads "${objfile}" "${binfile}" executable $opts] != "") } {
    return -1
}

# Now we can proceed with the real testing.

# Start with a fresh gdb.

clean_restart ${testfile}

# 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

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-thread.exp
    return -1
}

gdb_test_multiple "info threads" "threads are supported" {
    -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"

# Drop corefile
set core_supported [gdb_gcore_cmd "$corefile" "save a corefile"]

if {!$core_supported} {
  return -1
}


# Test the uninitialized thread list.
# Provide the case of glibc td_thr_get_info handling of:
# /* Special case for the main thread before initialization.  */

foreach symbol {__stack_user stack_used} {
    set test "clear ${symbol}.next"
    gdb_test_multiple "p *(void **) &${symbol} = 0" $test {
	-re " = \\(void \\*\\) 0x0\r\n$gdb_prompt $" {
	    pass $test
	}
	-re "No symbol \"${symbol}\" in current context\\.\r\n$gdb_prompt $" {
	    xfail $test
	    # Do not do the verification.
	    set core0file ""
	}
    }
}

if {"$core0file" != ""} {
    gdb_test "gcore $core0file" "Saved corefile .*" "save a zeroed-threads corefile"
}


# Now restart gdb and load the corefile.
clean_restart ${testfile}

foreach name { corefile core0file } { with_test_prefix $name {
    set core_loaded [gdb_core_cmd [subst $$name] "re-load generated corefile"]
    if { $core_loaded == -1 } {
	# No use proceeding from here.
	continue
    }

    # 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"
}}
