mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-06 07:33:08 +00:00
gdb/testsuite: also compile foll-exec.exp as C++
For a long time, Fedora GDB has carried a test that performs some basic testing that GDB can handle 'catch exec' related commands for a C++ executable. The exact motivation for this test has been lost in the mists of time, but looking at the test script, the concern seems to be that GDB would have problems inserting C++ related internal breakpoints if a non C++ process is execd from a C++ one. There's no actual GDB fix associated with the Fedora test. This usually means that the issue was fixed upstream long ago. This patch does seem to date from around 2010ish (or maybe earlier). Having a look through the upstream tests, I cannot see anything that covers this sort of thing (C++ to C exec calls), and I figure it cannot hurt to have some additional testing in this area, and so I wrote this patch. I've taken the existing foll-exec.exp test, which compiles a C executable and then execs a different C executable, and split it into two copies. We now have foll-exec-c.exp and foll-exec-c++.exp. These tests compile a C and C++ executable respectively. Then within each of these scripts both a C and C++ helper application is built, which can then be execd from the main test executable. And so, we now cover 4 cases, the initial executable can be C or C++, and the execd process can be C or C++. As expected, everything passes. This is just increasing test coverage. Approved-By: Simon Marchi <simon.marchi@efficios.com>
This commit is contained in:
24
gdb/testsuite/gdb.base/foll-exec-c++.exp
Normal file
24
gdb/testsuite/gdb.base/foll-exec-c++.exp
Normal file
@@ -0,0 +1,24 @@
|
||||
# Copyright 2025 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 is part of the gdb testsuite
|
||||
|
||||
# See foll-exec.exp.tcl for test details. This file runs the test
|
||||
# using the C++ compiler.
|
||||
|
||||
require allow_cplus_tests
|
||||
set lang c++
|
||||
|
||||
source $srcdir/$subdir/foll-exec.exp.tcl
|
||||
23
gdb/testsuite/gdb.base/foll-exec-c.exp
Normal file
23
gdb/testsuite/gdb.base/foll-exec-c.exp
Normal file
@@ -0,0 +1,23 @@
|
||||
# Copyright 2025 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 is part of the gdb testsuite
|
||||
|
||||
# See foll-exec.exp.tcl for test details. This file runs the test
|
||||
# using the C compiler.
|
||||
|
||||
set lang c
|
||||
|
||||
source $srcdir/$subdir/foll-exec.exp.tcl
|
||||
@@ -19,7 +19,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libgen.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
int global_i = 100;
|
||||
@@ -29,15 +30,23 @@ int main (int argc, char ** argv)
|
||||
int local_j = global_i + 1;
|
||||
int local_k = local_j + 1;
|
||||
char prog[PATH_MAX];
|
||||
int len;
|
||||
size_t len = PATH_MAX - 1;
|
||||
|
||||
printf ("foll-exec is about to execlp(execd-prog)...\n");
|
||||
printf ("foll-exec is about to execlp(%s)...\n", EXECD_PROG);
|
||||
|
||||
strcpy (prog, argv[0]);
|
||||
len = strlen (prog);
|
||||
/* Replace "foll-exec" with "execd-prog". */
|
||||
memcpy (prog + len - 9, "execd-prog", 10);
|
||||
prog[len + 1] = 0;
|
||||
prog [len] = '\0';
|
||||
|
||||
strncpy (prog, dirname (argv[0]), len);
|
||||
len -= strlen (prog);
|
||||
assert (len > 0);
|
||||
|
||||
strncat (prog, "/", len);
|
||||
len -= 1;
|
||||
assert (len > 0);
|
||||
|
||||
strncat (prog, EXECD_PROG, len);
|
||||
len -= strlen (EXECD_PROG);
|
||||
assert (len > 0);
|
||||
|
||||
/* In the following function call, maximum line length exceed the limit 80.
|
||||
This is intentional and required for clang compiler such that complete
|
||||
@@ -45,7 +54,7 @@ int main (int argc, char ** argv)
|
||||
multi-line. */
|
||||
execlp (prog, /* tbreak-execlp */ prog, "execlp arg1 from foll-exec", (char *) 0);
|
||||
|
||||
printf ("foll-exec is about to execl(execd-prog)...\n");
|
||||
printf ("foll-exec is about to execl(%s)...\n", EXECD_PROG);
|
||||
|
||||
/* In the following function call, maximum line length exceed the limit 80.
|
||||
This is intentional and required for clang compiler such that complete
|
||||
@@ -61,7 +70,7 @@ int main (int argc, char ** argv)
|
||||
|
||||
argv[0] = prog;
|
||||
|
||||
printf ("foll-exec is about to execv(execd-prog)...\n");
|
||||
printf ("foll-exec is about to execv(%s)...\n", EXECD_PROG);
|
||||
|
||||
execv (prog, argv); /* tbreak-execv */
|
||||
}
|
||||
|
||||
@@ -22,33 +22,55 @@ require {istarget "*-linux*"}
|
||||
|
||||
standard_testfile foll-exec.c
|
||||
|
||||
set testfile2 "execd-prog"
|
||||
set srcfile2 ${testfile2}.c
|
||||
set binfile2 [standard_output_file ${testfile2}]
|
||||
|
||||
set compile_options debug
|
||||
|
||||
# build the first test case
|
||||
if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable $compile_options] != "" } {
|
||||
untested "failed to compile"
|
||||
return -1
|
||||
}
|
||||
|
||||
if { [is_remote target] } {
|
||||
gdb_remote_download target $binfile2
|
||||
}
|
||||
|
||||
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable $compile_options] != "" } {
|
||||
untested "failed to compile"
|
||||
return -1
|
||||
}
|
||||
|
||||
proc do_exec_tests {} {
|
||||
global binfile srcfile srcfile2 testfile testfile2
|
||||
# Compile a program that performs an exec as EXECER_LANG, and a
|
||||
# program that will be exec'd as EXECEE_LANG. Either language can be
|
||||
# 'c' or 'c++'. Then run various test associated with 'catch exec'
|
||||
# using the compiled programs.
|
||||
proc do_exec_tests { execer_lang execee_lang } {
|
||||
global srcfile testfile
|
||||
global gdb_prompt
|
||||
|
||||
# First compile the program to be exec'd, the execee.
|
||||
set execee_base_filename "execd-prog"
|
||||
set srcfile2 ${execee_base_filename}.c
|
||||
set execee_testfile "execd-prog-${execee_lang}"
|
||||
set execee_testfile_re [string_to_regexp $execee_testfile]
|
||||
set execee_binfile [standard_output_file $execee_testfile]
|
||||
|
||||
set execee_flags debug
|
||||
if { $execee_lang == "c++" } {
|
||||
lappend execee_flags "c++"
|
||||
}
|
||||
|
||||
if { [build_executable "failed to build $execee_testfile" $execee_testfile \
|
||||
$srcfile2 $execee_flags] == -1 } {
|
||||
return
|
||||
}
|
||||
|
||||
if { [is_remote target] } {
|
||||
gdb_remote_download target $execee_binfile
|
||||
}
|
||||
|
||||
|
||||
# Now compile the program to do the exec, the execer.
|
||||
set execer_testfile "$testfile-${execee_lang}"
|
||||
set execer_binfile [standard_output_file $execer_testfile]
|
||||
|
||||
set execer_flags debug
|
||||
if { $execer_lang == "c++" } {
|
||||
lappend execer_flags "c++"
|
||||
}
|
||||
lappend execer_flags "additional_flags=-DEXECD_PROG=\"${execee_testfile}\""
|
||||
|
||||
if { [build_executable "failed to build $execer_testfile" $execer_testfile \
|
||||
$srcfile $execer_flags] == -1 } {
|
||||
return
|
||||
}
|
||||
|
||||
# Now we can start running the tests.
|
||||
clean_restart $execer_binfile
|
||||
|
||||
# Start the program running, and stop at main.
|
||||
#
|
||||
if {![runto_main]} {
|
||||
return
|
||||
}
|
||||
@@ -71,7 +93,7 @@ proc do_exec_tests {} {
|
||||
return
|
||||
}
|
||||
|
||||
clean_restart $binfile
|
||||
clean_restart $execer_binfile
|
||||
|
||||
# Start the program running, and stop at main.
|
||||
#
|
||||
@@ -120,7 +142,7 @@ proc do_exec_tests {} {
|
||||
set execd_line [gdb_get_line_number "after-exec" $srcfile2]
|
||||
send_gdb "next\n"
|
||||
gdb_expect {
|
||||
-re ".*xecuting new program: .*${testfile2}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\
|
||||
-re ".*xecuting new program: .*${execee_testfile_re}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\
|
||||
{pass "step through execlp call"}
|
||||
-re "$gdb_prompt $" {fail "step through execlp call"}
|
||||
timeout {fail "(timeout) step through execlp call"}
|
||||
@@ -160,7 +182,7 @@ proc do_exec_tests {} {
|
||||
|
||||
# Explicitly kill this program, or a subsequent rerun actually runs
|
||||
# the exec'd program, not the original program...
|
||||
clean_restart $binfile
|
||||
clean_restart $execer_binfile
|
||||
|
||||
# Start the program running, and stop at main.
|
||||
#
|
||||
@@ -193,7 +215,7 @@ proc do_exec_tests {} {
|
||||
|
||||
send_gdb "continue\n"
|
||||
gdb_expect {
|
||||
-re ".*xecuting new program:.*${testfile2}.*Catchpoint .*(exec\'d .*${testfile2}).*$gdb_prompt $"\
|
||||
-re ".*xecuting new program:.*${execee_testfile_re}.*Catchpoint .*(exec\'d .*${execee_testfile_re}).*$gdb_prompt $"\
|
||||
{pass "hit catch exec"}
|
||||
-re "$gdb_prompt $" {fail "hit catch exec"}
|
||||
timeout {fail "(timeout) hit catch exec"}
|
||||
@@ -210,7 +232,7 @@ proc do_exec_tests {} {
|
||||
#
|
||||
set msg "info shows catchpoint exec pathname"
|
||||
gdb_test_multiple "info breakpoints" $msg {
|
||||
-re ".*catchpoint.*keep y.*exec, program \".*${testfile2}\".*$gdb_prompt $" {
|
||||
-re ".*catchpoint.*keep y.*exec, program \".*${execee_testfile_re}\".*$gdb_prompt $" {
|
||||
pass $msg
|
||||
}
|
||||
}
|
||||
@@ -228,7 +250,7 @@ proc do_exec_tests {} {
|
||||
|
||||
# Explicitly kill this program, or a subsequent rerun actually runs
|
||||
# the exec'd program, not the original program...
|
||||
clean_restart $binfile
|
||||
clean_restart $execer_binfile
|
||||
|
||||
# Start the program running, and stop at main.
|
||||
#
|
||||
@@ -269,7 +291,7 @@ proc do_exec_tests {} {
|
||||
#
|
||||
send_gdb "next 2\n"
|
||||
gdb_expect {
|
||||
-re ".*xecuting new program: .*${testfile2}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\
|
||||
-re ".*xecuting new program: .*${execee_testfile_re}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\
|
||||
{pass "step through execl call"}
|
||||
-re "$gdb_prompt $" {fail "step through execl call"}
|
||||
timeout {fail "(timeout) step through execl call"}
|
||||
@@ -295,7 +317,7 @@ proc do_exec_tests {} {
|
||||
|
||||
# Explicitly kill this program, or a subsequent rerun actually runs
|
||||
# the exec'd program, not the original program...
|
||||
clean_restart $binfile
|
||||
clean_restart $execer_binfile
|
||||
|
||||
# Start the program running, and stop at main.
|
||||
#
|
||||
@@ -330,7 +352,7 @@ proc do_exec_tests {} {
|
||||
}
|
||||
send_gdb "next\n"
|
||||
gdb_expect {
|
||||
-re ".*xecuting new program: .*${testfile2}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\
|
||||
-re ".*xecuting new program: .*${execee_testfile_re}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\
|
||||
{pass "step through execv call"}
|
||||
-re "$gdb_prompt $" {fail "step through execv call"}
|
||||
timeout {fail "(timeout) step through execv call"}
|
||||
@@ -356,7 +378,7 @@ proc do_exec_tests {} {
|
||||
|
||||
# Explicitly kill this program, or a subsequent rerun actually runs
|
||||
# the exec'd program, not the original program...
|
||||
clean_restart $binfile
|
||||
clean_restart $execer_binfile
|
||||
|
||||
# Start the program running, and stop at main.
|
||||
#
|
||||
@@ -370,13 +392,13 @@ proc do_exec_tests {} {
|
||||
#
|
||||
send_gdb "continue\n"
|
||||
gdb_expect {
|
||||
-re ".*xecuting new program: .*${testfile2}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\
|
||||
-re ".*xecuting new program: .*${execee_testfile_re}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\
|
||||
{pass "continue through exec"}
|
||||
-re "$gdb_prompt $" {fail "continue through exec"}
|
||||
timeout {fail "(timeout) continue through exec"}
|
||||
}
|
||||
}
|
||||
|
||||
clean_restart $binfile
|
||||
|
||||
do_exec_tests
|
||||
foreach_with_prefix execee_lang { c c++ } {
|
||||
do_exec_tests $lang $execee_lang
|
||||
}
|
||||
Reference in New Issue
Block a user