# Copyright 2008-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 test was created by modifying attach.exp.
# This file was created by Jeff Johnston <jjohnstn@redhat.com>.
# This file was updated by Jan Kratochvil <jan.kratochvil@redhat.com>.

# This test only works on Linux
if { ![isnative] || [is_remote host] || [target_info exists use_gdb_stub]
     || ![istarget *-linux*] } {
    continue
}

set testfile "attach-stopped"
set srcfile  ${testfile}.c
set binfile  ${objdir}/${subdir}/${testfile}
set escapedbinfile  [string_to_regexp ${objdir}/${subdir}/${testfile}]

#execute_anywhere "rm -f ${binfile}"
remote_exec build "rm -f ${binfile}"
# For debugging this test
#
#log_user 1

proc corefunc { threadtype } {
    global srcfile
    global binfile
    global escapedbinfile
    global srcdir
    global subdir
    global gdb_prompt

    if [get_compiler_info ${binfile}] {
	return -1
    }

    # Start the program running and then wait for a bit, to be sure
    # that it can be attached to.

    set testpid [eval exec $binfile &]

    # Avoid some race:
    sleep 2

    # Stop the program 
    remote_exec build "kill -s STOP ${testpid}"

    # Start with clean gdb
    gdb_exit
    gdb_start
    gdb_reinitialize_dir $srcdir/$subdir
    gdb_load ${binfile}

    # Verify that we can attach to the stopped process.
       
    set test "$threadtype: attach2 to stopped, after setting file"
    gdb_test_multiple "attach $testpid" "$test" {
	-re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*$gdb_prompt $" {
	    pass "$test"
	}
    }

    # ".*sleep.*clone.*" would fail on s390x as bt stops at START_THREAD there.
    if {[string equal $threadtype threaded]} {
	gdb_test "thread apply all bt" ".*sleep.*start_thread.*" "$threadtype: attach2 to stopped bt"
    } else {
	gdb_test "bt" ".*sleep.*main.*" "$threadtype: attach2 to stopped bt"
    }

    gdb_exit

    # Avoid some race:
    sleep 2

    # At this point, the process may be sleeping or T (Stopped) depending on
    # the Linux kernel version.  The behavior is not tested as it is not
    # dependent on GDB.

    remote_exec build "kill -9 ${testpid}"
}

# build the test case first without threads
#
if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
    untested "attach-stopped.exp (unthreaded)"
    return -1
}

corefunc nonthreaded

# build the test case first without threads
#
if  { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DUSE_THREADS}] != "" } {
    untested "attach-stopped.exp (threaded)"
    return -1
}

corefunc threaded

return 0
