[04/14] gdb/testsuite: Avoid fake failures when exit is unreliable

Message ID 20200207150003.8383-5-shahab.vahedi@gmail.com
State New, archived
Headers

Commit Message

Shahab Vahedi Feb. 7, 2020, 2:59 p.m. UTC
  From: Anton Kolesov <Anton.Kolesov@synopsys.com>

Tests that run in background will not run properly with targets that
doesn't have a proper "exit" function. For example, gdb.base/hook-stop
expects that after hook will resume inferior in background, there would
be a message "exited normally", however such a message will appear only
for targets with a proper exit(), while others will, for example, spin
in the infinite loop.

Test gdb.base/nextoverexit expects message "inferior exited normally",
which is present only when exit() actually halts the target.

Some tests in gdb.base/commands.exp has a flow that expects that
application can exit itself, which is not true when exit() function is
not reliable.

This patch makes those tests conditional - they run only if exit is
reliable.

gdb/testsuite/ChangeLog:
2016-07-13  Anton Kolesov <Anton.Kolesov@synopsys.com>

	* gdb.base/callexit.exp: Expect an "exit()" only if
	"exit_is_reliable" says so.
	* gdb.base/commands.exp: Likewise.
	* gdb.base/ena-dis-br.exp: Likewise.
	* gdb.base/hook-stop.exp: Likewise.
	* gdb.base/nextoverexit.exp: Likewise.
	* gdb.mi/mi-break.exp: Likewise.
	* gdb.mi/mi-exit-code.exp: Likewise.
	* gdb.mi/mi-simplerun.exp: Likewise.

Signed-off-by: Anton Kolesov <Anton.Kolesov@synopsys.com>
---
 gdb/testsuite/gdb.base/callexit.exp     |  7 +++++++
 gdb/testsuite/gdb.base/commands.exp     | 14 ++++++++++++++
 gdb/testsuite/gdb.base/ena-dis-br.exp   | 18 +++++++++++-------
 gdb/testsuite/gdb.base/hook-stop.exp    | 12 +++++++++++-
 gdb/testsuite/gdb.base/nextoverexit.exp |  7 +++++++
 gdb/testsuite/gdb.mi/mi-break.exp       |  5 +++++
 gdb/testsuite/gdb.mi/mi-exit-code.exp   |  5 +++++
 gdb/testsuite/gdb.mi/mi-simplerun.exp   |  5 +++++
 8 files changed, 65 insertions(+), 8 deletions(-)
  

Comments

Luis Machado Feb. 11, 2020, 8:10 a.m. UTC | #1
Hi,

On 2/7/20 11:59 AM, Shahab Vahedi wrote:
> From: Anton Kolesov <Anton.Kolesov@synopsys.com>
> 
> Tests that run in background will not run properly with targets that
> doesn't have a proper "exit" function. For example, gdb.base/hook-stop
> expects that after hook will resume inferior in background, there would
> be a message "exited normally", however such a message will appear only
> for targets with a proper exit(), while others will, for example, spin
> in the infinite loop.
> 
> Test gdb.base/nextoverexit expects message "inferior exited normally",
> which is present only when exit() actually halts the target.
> 
> Some tests in gdb.base/commands.exp has a flow that expects that
> application can exit itself, which is not true when exit() function is
> not reliable.
> 
> This patch makes those tests conditional - they run only if exit is
> reliable.

I don't know about this one. Doesn't your debugging stub have a way of 
detecting a call to exit, for example?

These changes seem to indicate you are using some custom/modified 
dejagnu board to run your tests. Is your target a qemu/probe that gdb 
connects to and then does the tests?

> 
> gdb/testsuite/ChangeLog:
> 2016-07-13  Anton Kolesov <Anton.Kolesov@synopsys.com>
> 
> 	* gdb.base/callexit.exp: Expect an "exit()" only if
> 	"exit_is_reliable" says so.
> 	* gdb.base/commands.exp: Likewise.
> 	* gdb.base/ena-dis-br.exp: Likewise.
> 	* gdb.base/hook-stop.exp: Likewise.
> 	* gdb.base/nextoverexit.exp: Likewise.
> 	* gdb.mi/mi-break.exp: Likewise.
> 	* gdb.mi/mi-exit-code.exp: Likewise.
> 	* gdb.mi/mi-simplerun.exp: Likewise.
> 
> Signed-off-by: Anton Kolesov <Anton.Kolesov@synopsys.com>
> ---
>   gdb/testsuite/gdb.base/callexit.exp     |  7 +++++++
>   gdb/testsuite/gdb.base/commands.exp     | 14 ++++++++++++++
>   gdb/testsuite/gdb.base/ena-dis-br.exp   | 18 +++++++++++-------
>   gdb/testsuite/gdb.base/hook-stop.exp    | 12 +++++++++++-
>   gdb/testsuite/gdb.base/nextoverexit.exp |  7 +++++++
>   gdb/testsuite/gdb.mi/mi-break.exp       |  5 +++++
>   gdb/testsuite/gdb.mi/mi-exit-code.exp   |  5 +++++
>   gdb/testsuite/gdb.mi/mi-simplerun.exp   |  5 +++++
>   8 files changed, 65 insertions(+), 8 deletions(-)
> 
> diff --git a/gdb/testsuite/gdb.base/callexit.exp b/gdb/testsuite/gdb.base/callexit.exp
> index 67ff48283646..4fc2d5a2669a 100644
> --- a/gdb/testsuite/gdb.base/callexit.exp
> +++ b/gdb/testsuite/gdb.base/callexit.exp
> @@ -28,6 +28,13 @@ if [target_info exists gdb,cannot_call_functions] {
>       continue
>   }
>   
> +# Some targets (for example baremetal ones) doesn't have exit() that actually
> +# exits anywhere.
> +if ![exit_is_reliable] {
> +    unsupported "This target doesn't have reliable exit() function."
> +    continue
> +}
> +
>   # Start with a fresh gdb.
>   
>   clean_restart ${binfile}
> diff --git a/gdb/testsuite/gdb.base/commands.exp b/gdb/testsuite/gdb.base/commands.exp
> index 869d0a81a4a7..fd92b3fa3111 100644
> --- a/gdb/testsuite/gdb.base/commands.exp
> +++ b/gdb/testsuite/gdb.base/commands.exp
> @@ -694,6 +694,13 @@ proc_with_prefix deprecated_command_test {} {
>   proc_with_prefix bp_deleted_in_command_test {} {
>       global gdb_prompt
>   
> +    # Flow of this test assumes that application will halt after reaching the
> +    # exit() function.
> +    if ![exit_is_reliable] {
> +	unsupported "Function exit() is not reliable on this board."
> +	return 0
> +    }
> +
>       delete_breakpoints
>   
>       # Create a breakpoint, and associate a command-list to it, with
> @@ -736,6 +743,13 @@ proc_with_prefix bp_deleted_in_command_test {} {
>   }
>   
>   proc_with_prefix temporary_breakpoint_commands {} {
> +    # Flow of this test assumes that application will halt after reaching the
> +    # exit() function.
> +    if ![exit_is_reliable] {
> +	unsupported "Function exit() is not reliable on this board."
> +	return 0
> +    }
> +
>       delete_breakpoints
>   
>       # Create a temporary breakpoint, and associate a commands list to it.
> diff --git a/gdb/testsuite/gdb.base/ena-dis-br.exp b/gdb/testsuite/gdb.base/ena-dis-br.exp
> index c338a0d51fa9..bf670cbae948 100644
> --- a/gdb/testsuite/gdb.base/ena-dis-br.exp
> +++ b/gdb/testsuite/gdb.base/ena-dis-br.exp
> @@ -295,13 +295,17 @@ gdb_test "continue 2" \
>   gdb_test "next" ".*$bp_location11\[ \t\]*marker1.*" \
>       "step after continue with ignore count"
>   
> -set test "continue with ignore count, not stopped at bpt"
> -gdb_test_multiple "continue 2" "$test" {
> -    -re "Not stopped at any breakpoint; argument ignored.*$gdb_prompt $" {
> -	pass "$test"
> -    }
> -    -re "No breakpoint number -1.*$gdb_prompt $" {
> -	kfail gdb/1689 "$test"
> +# Application is expected to reach an exit() here, so this can't be run if exit
> +# is not working.
> +if [exit_is_reliable] {
> +    set test "continue with ignore count, not stopped at bpt"
> +    gdb_test_multiple "continue 2" "$test" {
> +	-re "Not stopped at any breakpoint; argument ignored.*$gdb_prompt $" {
> +	    pass "$test"
> +	}
> +	-re "No breakpoint number -1.*$gdb_prompt $" {
> +	    kfail gdb/1689 "$test"
> +	}
>       }
>   }
>   
> diff --git a/gdb/testsuite/gdb.base/hook-stop.exp b/gdb/testsuite/gdb.base/hook-stop.exp
> index 6b49e39b7380..c9bc3d3b6438 100644
> --- a/gdb/testsuite/gdb.base/hook-stop.exp
> +++ b/gdb/testsuite/gdb.base/hook-stop.exp
> @@ -165,5 +165,15 @@ proc hook_stop_next {} {
>   hook_stop_before_frame
>   hook_stop_kill
>   hook_stop_continue_fg
> -hook_stop_continue_bg
> +
> +# Tests that run in background will not run properly with targets that
> +# doesn't have a proper "exit" function. For example, this particular
> +# test expects that after hook will resume inferior in background, there
> +# would be a message "exited normally", however such a message will
> +# appear only for targets with a proper # exit(), while others will, for
> +# example, spin in the infinite loop.
> +if [exit_is_reliable] {
> +    hook_stop_continue_bg
> +}
> +
>   hook_stop_next
> diff --git a/gdb/testsuite/gdb.base/nextoverexit.exp b/gdb/testsuite/gdb.base/nextoverexit.exp
> index 30eafef675ff..fcea35762b00 100644
> --- a/gdb/testsuite/gdb.base/nextoverexit.exp
> +++ b/gdb/testsuite/gdb.base/nextoverexit.exp
> @@ -14,6 +14,13 @@
>   
>   standard_testfile
>   
> +# This tests expects message "inferior exited normally", which is present only
> +# when exit() actually halts the target.
> +if ![exit_is_reliable] {
> +    unsupported "Function exit() is not reliable on this board."
> +    return 0
> +}
> +
>   if {[prepare_for_testing "failed to prepare" $testfile $testfile.c]} {
>       return -1
>   }
> diff --git a/gdb/testsuite/gdb.mi/mi-break.exp b/gdb/testsuite/gdb.mi/mi-break.exp
> index 1149bb34c8dc..acec246f52ee 100644
> --- a/gdb/testsuite/gdb.mi/mi-break.exp
> +++ b/gdb/testsuite/gdb.mi/mi-break.exp
> @@ -244,6 +244,11 @@ proc test_disabled_creation {} {
>   proc test_breakpoint_commands {} {
>       global line_callee2_body
>   
> +    if ![exit_is_reliable] {
> +	unsupported "This test requires working exit() function."
> +	return 0
> +    }
> +
>       set bp_no_script \
>   	[mi_create_breakpoint "basics.c:callee2" \
>   	     "breakpoint commands: insert breakpoint at basics.c:callee2" \
> diff --git a/gdb/testsuite/gdb.mi/mi-exit-code.exp b/gdb/testsuite/gdb.mi/mi-exit-code.exp
> index f10b49cee0f8..fb5c693597da 100644
> --- a/gdb/testsuite/gdb.mi/mi-exit-code.exp
> +++ b/gdb/testsuite/gdb.mi/mi-exit-code.exp
> @@ -23,6 +23,11 @@ if [mi_gdb_start] {
>   
>   standard_testfile
>   
> +if ![exit_is_reliable] {
> +    unsupported "Function exit() is not reliable on this board."
> +    return 0
> +}
> +
>   if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
>       untested "failed to compile"
>       return -1
> diff --git a/gdb/testsuite/gdb.mi/mi-simplerun.exp b/gdb/testsuite/gdb.mi/mi-simplerun.exp
> index 20a079ead896..ce19122803da 100644
> --- a/gdb/testsuite/gdb.mi/mi-simplerun.exp
> +++ b/gdb/testsuite/gdb.mi/mi-simplerun.exp
> @@ -177,6 +177,11 @@ proc test_program_termination {} {
>       # -exec-abort
>       # (normal termination of inferior)
>   
> +    if ![exit_is_reliable] {
> +	unsupported "Function exit() is not reliable on this board."
> +	return
> +    }
> +
>       mi_execute_to "exec-continue" "exited-normally" "" "" "" "" "" "continue to end"
>   }
>   
>
  
Shahab Vahedi Feb. 18, 2020, 3:41 p.m. UTC | #2
On 2/11/20 9:10 AM, Luis Machado wrote:
> Hi,

> 

> On 2/7/20 11:59 AM, Shahab Vahedi wrote:

>> From: Anton Kolesov <Anton.Kolesov@synopsys.com>

>>

>> Tests that run in background will not run properly with targets that

>> doesn't have a proper "exit" function. For example, gdb.base/hook-stop

>> expects that after hook will resume inferior in background, there would

>> be a message "exited normally", however such a message will appear only

>> for targets with a proper exit(), while others will, for example, spin

>> in the infinite loop.

>>

>> Test gdb.base/nextoverexit expects message "inferior exited normally",

>> which is present only when exit() actually halts the target.

>>

>> Some tests in gdb.base/commands.exp has a flow that expects that

>> application can exit itself, which is not true when exit() function is

>> not reliable.

>>

>> This patch makes those tests conditional - they run only if exit is

>> reliable.

> 

> I don't know about this one. Doesn't your debugging stub have a way of detecting a call to exit, for example?


There is some testglue (gdb_tg.o) that prints to stdout if exit has happened with values other than 0. However, I believe the issue here is about running on a board. Anton is the best for responding to this.

> 

> These changes seem to indicate you are using some custom/modified dejagnu board to run your tests. Is your target a qemu/probe that gdb connects to and then does the tests?

That is correct. The target has never been qemu/probe. I believe it has been the in-house simulator and also some real boards.

> 

>>

>> gdb/testsuite/ChangeLog:

>> 2016-07-13  Anton Kolesov <Anton.Kolesov@synopsys.com>

>>

>>     * gdb.base/callexit.exp: Expect an "exit()" only if

>>     "exit_is_reliable" says so.

>>     * gdb.base/commands.exp: Likewise.

>>     * gdb.base/ena-dis-br.exp: Likewise.

>>     * gdb.base/hook-stop.exp: Likewise.

>>     * gdb.base/nextoverexit.exp: Likewise.

>>     * gdb.mi/mi-break.exp: Likewise.

>>     * gdb.mi/mi-exit-code.exp: Likewise.

>>     * gdb.mi/mi-simplerun.exp: Likewise.

>>

>> Signed-off-by: Anton Kolesov <Anton.Kolesov@synopsys.com>

>> ---

>>   gdb/testsuite/gdb.base/callexit.exp     |  7 +++++++

>>   gdb/testsuite/gdb.base/commands.exp     | 14 ++++++++++++++

>>   gdb/testsuite/gdb.base/ena-dis-br.exp   | 18 +++++++++++-------

>>   gdb/testsuite/gdb.base/hook-stop.exp    | 12 +++++++++++-

>>   gdb/testsuite/gdb.base/nextoverexit.exp |  7 +++++++

>>   gdb/testsuite/gdb.mi/mi-break.exp       |  5 +++++

>>   gdb/testsuite/gdb.mi/mi-exit-code.exp   |  5 +++++

>>   gdb/testsuite/gdb.mi/mi-simplerun.exp   |  5 +++++

>>   8 files changed, 65 insertions(+), 8 deletions(-)

>>

>> diff --git a/gdb/testsuite/gdb.base/callexit.exp b/gdb/testsuite/gdb.base/callexit.exp

>> index 67ff48283646..4fc2d5a2669a 100644

>> --- a/gdb/testsuite/gdb.base/callexit.exp

>> +++ b/gdb/testsuite/gdb.base/callexit.exp

>> @@ -28,6 +28,13 @@ if [target_info exists gdb,cannot_call_functions] {

>>       continue

>>   }

>>   +# Some targets (for example baremetal ones) doesn't have exit() that actually

>> +# exits anywhere.

>> +if ![exit_is_reliable] {

>> +    unsupported "This target doesn't have reliable exit() function."

>> +    continue

>> +}

>> +

>>   # Start with a fresh gdb.

>>     clean_restart ${binfile}

>> diff --git a/gdb/testsuite/gdb.base/commands.exp b/gdb/testsuite/gdb.base/commands.exp

>> index 869d0a81a4a7..fd92b3fa3111 100644

>> --- a/gdb/testsuite/gdb.base/commands.exp

>> +++ b/gdb/testsuite/gdb.base/commands.exp

>> @@ -694,6 +694,13 @@ proc_with_prefix deprecated_command_test {} {

>>   proc_with_prefix bp_deleted_in_command_test {} {

>>       global gdb_prompt

>>   +    # Flow of this test assumes that application will halt after reaching the

>> +    # exit() function.

>> +    if ![exit_is_reliable] {

>> +    unsupported "Function exit() is not reliable on this board."

>> +    return 0

>> +    }

>> +

>>       delete_breakpoints

>>         # Create a breakpoint, and associate a command-list to it, with

>> @@ -736,6 +743,13 @@ proc_with_prefix bp_deleted_in_command_test {} {

>>   }

>>     proc_with_prefix temporary_breakpoint_commands {} {

>> +    # Flow of this test assumes that application will halt after reaching the

>> +    # exit() function.

>> +    if ![exit_is_reliable] {

>> +    unsupported "Function exit() is not reliable on this board."

>> +    return 0

>> +    }

>> +

>>       delete_breakpoints

>>         # Create a temporary breakpoint, and associate a commands list to it.

>> diff --git a/gdb/testsuite/gdb.base/ena-dis-br.exp b/gdb/testsuite/gdb.base/ena-dis-br.exp

>> index c338a0d51fa9..bf670cbae948 100644

>> --- a/gdb/testsuite/gdb.base/ena-dis-br.exp

>> +++ b/gdb/testsuite/gdb.base/ena-dis-br.exp

>> @@ -295,13 +295,17 @@ gdb_test "continue 2" \

>>   gdb_test "next" ".*$bp_location11\[ \t\]*marker1.*" \

>>       "step after continue with ignore count"

>>   -set test "continue with ignore count, not stopped at bpt"

>> -gdb_test_multiple "continue 2" "$test" {

>> -    -re "Not stopped at any breakpoint; argument ignored.*$gdb_prompt $" {

>> -    pass "$test"

>> -    }

>> -    -re "No breakpoint number -1.*$gdb_prompt $" {

>> -    kfail gdb/1689 "$test"

>> +# Application is expected to reach an exit() here, so this can't be run if exit

>> +# is not working.

>> +if [exit_is_reliable] {

>> +    set test "continue with ignore count, not stopped at bpt"

>> +    gdb_test_multiple "continue 2" "$test" {

>> +    -re "Not stopped at any breakpoint; argument ignored.*$gdb_prompt $" {

>> +        pass "$test"

>> +    }

>> +    -re "No breakpoint number -1.*$gdb_prompt $" {

>> +        kfail gdb/1689 "$test"

>> +    }

>>       }

>>   }

>>   diff --git a/gdb/testsuite/gdb.base/hook-stop.exp b/gdb/testsuite/gdb.base/hook-stop.exp

>> index 6b49e39b7380..c9bc3d3b6438 100644

>> --- a/gdb/testsuite/gdb.base/hook-stop.exp

>> +++ b/gdb/testsuite/gdb.base/hook-stop.exp

>> @@ -165,5 +165,15 @@ proc hook_stop_next {} {

>>   hook_stop_before_frame

>>   hook_stop_kill

>>   hook_stop_continue_fg

>> -hook_stop_continue_bg

>> +

>> +# Tests that run in background will not run properly with targets that

>> +# doesn't have a proper "exit" function. For example, this particular

>> +# test expects that after hook will resume inferior in background, there

>> +# would be a message "exited normally", however such a message will

>> +# appear only for targets with a proper # exit(), while others will, for

>> +# example, spin in the infinite loop.

>> +if [exit_is_reliable] {

>> +    hook_stop_continue_bg

>> +}

>> +

>>   hook_stop_next

>> diff --git a/gdb/testsuite/gdb.base/nextoverexit.exp b/gdb/testsuite/gdb.base/nextoverexit.exp

>> index 30eafef675ff..fcea35762b00 100644

>> --- a/gdb/testsuite/gdb.base/nextoverexit.exp

>> +++ b/gdb/testsuite/gdb.base/nextoverexit.exp

>> @@ -14,6 +14,13 @@

>>     standard_testfile

>>   +# This tests expects message "inferior exited normally", which is present only

>> +# when exit() actually halts the target.

>> +if ![exit_is_reliable] {

>> +    unsupported "Function exit() is not reliable on this board."

>> +    return 0

>> +}

>> +

>>   if {[prepare_for_testing "failed to prepare" $testfile $testfile.c]} {

>>       return -1

>>   }

>> diff --git a/gdb/testsuite/gdb.mi/mi-break.exp b/gdb/testsuite/gdb.mi/mi-break.exp

>> index 1149bb34c8dc..acec246f52ee 100644

>> --- a/gdb/testsuite/gdb.mi/mi-break.exp

>> +++ b/gdb/testsuite/gdb.mi/mi-break.exp

>> @@ -244,6 +244,11 @@ proc test_disabled_creation {} {

>>   proc test_breakpoint_commands {} {

>>       global line_callee2_body

>>   +    if ![exit_is_reliable] {

>> +    unsupported "This test requires working exit() function."

>> +    return 0

>> +    }

>> +

>>       set bp_no_script \

>>       [mi_create_breakpoint "basics.c:callee2" \

>>            "breakpoint commands: insert breakpoint at basics.c:callee2" \

>> diff --git a/gdb/testsuite/gdb.mi/mi-exit-code.exp b/gdb/testsuite/gdb.mi/mi-exit-code.exp

>> index f10b49cee0f8..fb5c693597da 100644

>> --- a/gdb/testsuite/gdb.mi/mi-exit-code.exp

>> +++ b/gdb/testsuite/gdb.mi/mi-exit-code.exp

>> @@ -23,6 +23,11 @@ if [mi_gdb_start] {

>>     standard_testfile

>>   +if ![exit_is_reliable] {

>> +    unsupported "Function exit() is not reliable on this board."

>> +    return 0

>> +}

>> +

>>   if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {

>>       untested "failed to compile"

>>       return -1

>> diff --git a/gdb/testsuite/gdb.mi/mi-simplerun.exp b/gdb/testsuite/gdb.mi/mi-simplerun.exp

>> index 20a079ead896..ce19122803da 100644

>> --- a/gdb/testsuite/gdb.mi/mi-simplerun.exp

>> +++ b/gdb/testsuite/gdb.mi/mi-simplerun.exp

>> @@ -177,6 +177,11 @@ proc test_program_termination {} {

>>       # -exec-abort

>>       # (normal termination of inferior)

>>   +    if ![exit_is_reliable] {

>> +    unsupported "Function exit() is not reliable on this board."

>> +    return

>> +    }

>> +

>>       mi_execute_to "exec-continue" "exited-normally" "" "" "" "" "" "continue to end"

>>   }

>>
  
Anton Kolesov Feb. 25, 2020, 7:46 a.m. UTC | #3
> -----Original Message-----

> From: Shahab Vahedi

> Sent: Tuesday, February 18, 2020 18:42

> To: Luis Machado <luis.machado@linaro.org>; Shahab Vahedi

> <shahab.vahedi@gmail.com>; gdb-patches@sourceware.org

> Cc: Francois Bedard <fbedard@synopsys.com>; Anton Kolesov

> <akolesov@synopsys.com>

> Subject: Re: [PATCH 04/14] gdb/testsuite: Avoid fake failures when exit is

> unreliable

> 

> On 2/11/20 9:10 AM, Luis Machado wrote:

> > Hi,

> >

> > On 2/7/20 11:59 AM, Shahab Vahedi wrote:

> >> From: Anton Kolesov <Anton.Kolesov@synopsys.com>

> >>

> >>

> >> This patch makes those tests conditional - they run only if exit is

> >> reliable.

> >

> > I don't know about this one. Doesn't your debugging stub have a way of

> detecting a call to exit, for example?

> 

> There is some testglue (gdb_tg.o) that prints to stdout if exit has happened

> with values other than 0. However, I believe the issue here is about running on

> a board. Anton is the best for responding to this.


ARC gdb-servers don't detect call to exit - they are mostly "dumb" stubs that
defer to GDB client to do the application-level work, or in this case it is
testsuite's job to detect that _exit has been called. In general test suite
handle this properly - it sets breakpoint at _exit call and treats first
argument to invocation as exit code, however certain test cases expect
application to really exit, and IIRC the purpose of this patch is to skip
those test on a baremetal target - we'd need a semihosting library or equivalent,
and that is not fully supported in ARC gdbservers - or better to say it is not
supported at all in most of them.

> 

> >

> > These changes seem to indicate you are using some custom/modified

> dejagnu board to run your tests. Is your target a qemu/probe that gdb

> connects to and then does the tests?

> That is correct. The target has never been qemu/probe. I believe it has been

> the in-house simulator and also some real boards.


I've used proprietary simulator with built-in GDB-server and OpenOCD. There is
also support for ARC in other GDB-servers developed by Synopsys and
3rd-parties, each being a distinct implementation. Board files can be found at 
https://github.com/foss-for-synopsys-dwc-arc-processors/toolchain/blob/arc-releases/dejagnu/baseboards/arc-nsim.exp
https://github.com/foss-for-synopsys-dwc-arc-processors/toolchain/blob/arc-releases/dejagnu/baseboards/arc-openocd.exp
and their dependencies are in the same GitHub repository.
  
Andrew Burgess Feb. 26, 2020, 8:42 p.m. UTC | #4
* Shahab Vahedi <shahab.vahedi@gmail.com> [2020-02-07 15:59:53 +0100]:

> From: Anton Kolesov <Anton.Kolesov@synopsys.com>
> 
> Tests that run in background will not run properly with targets that
> doesn't have a proper "exit" function. For example, gdb.base/hook-stop
> expects that after hook will resume inferior in background, there would
> be a message "exited normally", however such a message will appear only
> for targets with a proper exit(), while others will, for example, spin
> in the infinite loop.
> 
> Test gdb.base/nextoverexit expects message "inferior exited normally",
> which is present only when exit() actually halts the target.
> 
> Some tests in gdb.base/commands.exp has a flow that expects that
> application can exit itself, which is not true when exit() function is
> not reliable.
> 
> This patch makes those tests conditional - they run only if exit is
> reliable.
> 
> gdb/testsuite/ChangeLog:
> 2016-07-13  Anton Kolesov <Anton.Kolesov@synopsys.com>
> 
> 	* gdb.base/callexit.exp: Expect an "exit()" only if
> 	"exit_is_reliable" says so.
> 	* gdb.base/commands.exp: Likewise.
> 	* gdb.base/ena-dis-br.exp: Likewise.
> 	* gdb.base/hook-stop.exp: Likewise.
> 	* gdb.base/nextoverexit.exp: Likewise.
> 	* gdb.mi/mi-break.exp: Likewise.
> 	* gdb.mi/mi-exit-code.exp: Likewise.
> 	* gdb.mi/mi-simplerun.exp: Likewise.
> 
> Signed-off-by: Anton Kolesov <Anton.Kolesov@synopsys.com>
> ---
>  gdb/testsuite/gdb.base/callexit.exp     |  7 +++++++
>  gdb/testsuite/gdb.base/commands.exp     | 14 ++++++++++++++
>  gdb/testsuite/gdb.base/ena-dis-br.exp   | 18 +++++++++++-------
>  gdb/testsuite/gdb.base/hook-stop.exp    | 12 +++++++++++-
>  gdb/testsuite/gdb.base/nextoverexit.exp |  7 +++++++
>  gdb/testsuite/gdb.mi/mi-break.exp       |  5 +++++
>  gdb/testsuite/gdb.mi/mi-exit-code.exp   |  5 +++++
>  gdb/testsuite/gdb.mi/mi-simplerun.exp   |  5 +++++
>  8 files changed, 65 insertions(+), 8 deletions(-)
> 
> diff --git a/gdb/testsuite/gdb.base/callexit.exp b/gdb/testsuite/gdb.base/callexit.exp
> index 67ff48283646..4fc2d5a2669a 100644
> --- a/gdb/testsuite/gdb.base/callexit.exp
> +++ b/gdb/testsuite/gdb.base/callexit.exp
> @@ -28,6 +28,13 @@ if [target_info exists gdb,cannot_call_functions] {
>      continue
>  }
>  
> +# Some targets (for example baremetal ones) doesn't have exit() that actually
> +# exits anywhere.
> +if ![exit_is_reliable] {
> +    unsupported "This target doesn't have reliable exit() function."
> +    continue
> +}

When the `if' check is at the top level I think you'd be better off
dropping the comment as the code is pretty self-explanatory, maybe
you'd be better putting more detail onto the comment on
'exit_is_reliable' itself.  I think this applies to every case where
the comment just says, 'if exit is not reliable, don't run this test'
as I think that's obvious from the code, if there's cases where more
detail is required then by all means, keep the comments.

Also the message in 'unsupported' shouldn't start with a capital
letter.

> +
>  # Start with a fresh gdb.
>  
>  clean_restart ${binfile}
> diff --git a/gdb/testsuite/gdb.base/commands.exp b/gdb/testsuite/gdb.base/commands.exp
> index 869d0a81a4a7..fd92b3fa3111 100644
> --- a/gdb/testsuite/gdb.base/commands.exp
> +++ b/gdb/testsuite/gdb.base/commands.exp
> @@ -694,6 +694,13 @@ proc_with_prefix deprecated_command_test {} {
>  proc_with_prefix bp_deleted_in_command_test {} {
>      global gdb_prompt
>  
> +    # Flow of this test assumes that application will halt after reaching the
> +    # exit() function.
> +    if ![exit_is_reliable] {
> +	unsupported "Function exit() is not reliable on this board."
> +	return 0
> +    }
> +
>      delete_breakpoints
>  
>      # Create a breakpoint, and associate a command-list to it, with
> @@ -736,6 +743,13 @@ proc_with_prefix bp_deleted_in_command_test {} {
>  }
>  
>  proc_with_prefix temporary_breakpoint_commands {} {
> +    # Flow of this test assumes that application will halt after reaching the
> +    # exit() function.
> +    if ![exit_is_reliable] {
> +	unsupported "Function exit() is not reliable on this board."
> +	return 0
> +    }
> +
>      delete_breakpoints
>  
>      # Create a temporary breakpoint, and associate a commands list to it.
> diff --git a/gdb/testsuite/gdb.base/ena-dis-br.exp b/gdb/testsuite/gdb.base/ena-dis-br.exp
> index c338a0d51fa9..bf670cbae948 100644
> --- a/gdb/testsuite/gdb.base/ena-dis-br.exp
> +++ b/gdb/testsuite/gdb.base/ena-dis-br.exp
> @@ -295,13 +295,17 @@ gdb_test "continue 2" \
>  gdb_test "next" ".*$bp_location11\[ \t\]*marker1.*" \
>      "step after continue with ignore count"
>  
> -set test "continue with ignore count, not stopped at bpt"
> -gdb_test_multiple "continue 2" "$test" {
> -    -re "Not stopped at any breakpoint; argument ignored.*$gdb_prompt $" {
> -	pass "$test"
> -    }
> -    -re "No breakpoint number -1.*$gdb_prompt $" {
> -	kfail gdb/1689 "$test"
> +# Application is expected to reach an exit() here, so this can't be run if exit
> +# is not working.
> +if [exit_is_reliable] {
> +    set test "continue with ignore count, not stopped at bpt"
> +    gdb_test_multiple "continue 2" "$test" {
> +	-re "Not stopped at any breakpoint; argument ignored.*$gdb_prompt $" {
> +	    pass "$test"
> +	}
> +	-re "No breakpoint number -1.*$gdb_prompt $" {
> +	    kfail gdb/1689 "$test"
> +	}
>      }
>  }
>  
> diff --git a/gdb/testsuite/gdb.base/hook-stop.exp b/gdb/testsuite/gdb.base/hook-stop.exp
> index 6b49e39b7380..c9bc3d3b6438 100644
> --- a/gdb/testsuite/gdb.base/hook-stop.exp
> +++ b/gdb/testsuite/gdb.base/hook-stop.exp
> @@ -165,5 +165,15 @@ proc hook_stop_next {} {
>  hook_stop_before_frame
>  hook_stop_kill
>  hook_stop_continue_fg
> -hook_stop_continue_bg
> +
> +# Tests that run in background will not run properly with targets that
> +# doesn't have a proper "exit" function. For example, this particular
> +# test expects that after hook will resume inferior in background, there
> +# would be a message "exited normally", however such a message will
> +# appear only for targets with a proper # exit(), while others will, for
> +# example, spin in the infinite loop.

I found this comment pretty confused, how about:

  # Tests that run in background will not run properly with targets
  # that doesn't have a proper "exit" function.  This test expects
  # that the after hook will resume the inferior in the background,
  # after which there would be a message "inferior exited normally".
  # Such a message will appear only for targets with a proper exit()
  # function, if the target simply spins in a loop instead of exiting
  # then the message will never appear.

What wasn't clear to me when I thought about this though was what does
your target actually do in this case?  You say in another mail that
your board file places a breakpoint on _exit and extracts the return
value from there - is that true for the GDB tests too?  Doesn't that
mean you actually hit the breakpoint in this case?

I'm not suggesting we should change the test to expect a breakpoint
hit, I'm more curious...

Thanks,
Andrew

> +if [exit_is_reliable] {
> +    hook_stop_continue_bg
> +}
> +
>  hook_stop_next
> diff --git a/gdb/testsuite/gdb.base/nextoverexit.exp b/gdb/testsuite/gdb.base/nextoverexit.exp
> index 30eafef675ff..fcea35762b00 100644
> --- a/gdb/testsuite/gdb.base/nextoverexit.exp
> +++ b/gdb/testsuite/gdb.base/nextoverexit.exp
> @@ -14,6 +14,13 @@
>  
>  standard_testfile
>  
> +# This tests expects message "inferior exited normally", which is present only
> +# when exit() actually halts the target.
> +if ![exit_is_reliable] {
> +    unsupported "Function exit() is not reliable on this board."
> +    return 0
> +}
> +
>  if {[prepare_for_testing "failed to prepare" $testfile $testfile.c]} {
>      return -1
>  }
> diff --git a/gdb/testsuite/gdb.mi/mi-break.exp b/gdb/testsuite/gdb.mi/mi-break.exp
> index 1149bb34c8dc..acec246f52ee 100644
> --- a/gdb/testsuite/gdb.mi/mi-break.exp
> +++ b/gdb/testsuite/gdb.mi/mi-break.exp
> @@ -244,6 +244,11 @@ proc test_disabled_creation {} {
>  proc test_breakpoint_commands {} {
>      global line_callee2_body
>  
> +    if ![exit_is_reliable] {
> +	unsupported "This test requires working exit() function."
> +	return 0
> +    }
> +
>      set bp_no_script \
>  	[mi_create_breakpoint "basics.c:callee2" \
>  	     "breakpoint commands: insert breakpoint at basics.c:callee2" \
> diff --git a/gdb/testsuite/gdb.mi/mi-exit-code.exp b/gdb/testsuite/gdb.mi/mi-exit-code.exp
> index f10b49cee0f8..fb5c693597da 100644
> --- a/gdb/testsuite/gdb.mi/mi-exit-code.exp
> +++ b/gdb/testsuite/gdb.mi/mi-exit-code.exp
> @@ -23,6 +23,11 @@ if [mi_gdb_start] {
>  
>  standard_testfile
>  
> +if ![exit_is_reliable] {
> +    unsupported "Function exit() is not reliable on this board."
> +    return 0
> +}
> +
>  if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
>      untested "failed to compile"
>      return -1
> diff --git a/gdb/testsuite/gdb.mi/mi-simplerun.exp b/gdb/testsuite/gdb.mi/mi-simplerun.exp
> index 20a079ead896..ce19122803da 100644
> --- a/gdb/testsuite/gdb.mi/mi-simplerun.exp
> +++ b/gdb/testsuite/gdb.mi/mi-simplerun.exp
> @@ -177,6 +177,11 @@ proc test_program_termination {} {
>      # -exec-abort
>      # (normal termination of inferior)
>  
> +    if ![exit_is_reliable] {
> +	unsupported "Function exit() is not reliable on this board."
> +	return
> +    }
> +
>      mi_execute_to "exec-continue" "exited-normally" "" "" "" "" "" "continue to end"
>  }
>  
> -- 
> 2.25.0
>
  

Patch

diff --git a/gdb/testsuite/gdb.base/callexit.exp b/gdb/testsuite/gdb.base/callexit.exp
index 67ff48283646..4fc2d5a2669a 100644
--- a/gdb/testsuite/gdb.base/callexit.exp
+++ b/gdb/testsuite/gdb.base/callexit.exp
@@ -28,6 +28,13 @@  if [target_info exists gdb,cannot_call_functions] {
     continue
 }
 
+# Some targets (for example baremetal ones) doesn't have exit() that actually
+# exits anywhere.
+if ![exit_is_reliable] {
+    unsupported "This target doesn't have reliable exit() function."
+    continue
+}
+
 # Start with a fresh gdb.
 
 clean_restart ${binfile}
diff --git a/gdb/testsuite/gdb.base/commands.exp b/gdb/testsuite/gdb.base/commands.exp
index 869d0a81a4a7..fd92b3fa3111 100644
--- a/gdb/testsuite/gdb.base/commands.exp
+++ b/gdb/testsuite/gdb.base/commands.exp
@@ -694,6 +694,13 @@  proc_with_prefix deprecated_command_test {} {
 proc_with_prefix bp_deleted_in_command_test {} {
     global gdb_prompt
 
+    # Flow of this test assumes that application will halt after reaching the
+    # exit() function.
+    if ![exit_is_reliable] {
+	unsupported "Function exit() is not reliable on this board."
+	return 0
+    }
+
     delete_breakpoints
 
     # Create a breakpoint, and associate a command-list to it, with
@@ -736,6 +743,13 @@  proc_with_prefix bp_deleted_in_command_test {} {
 }
 
 proc_with_prefix temporary_breakpoint_commands {} {
+    # Flow of this test assumes that application will halt after reaching the
+    # exit() function.
+    if ![exit_is_reliable] {
+	unsupported "Function exit() is not reliable on this board."
+	return 0
+    }
+
     delete_breakpoints
 
     # Create a temporary breakpoint, and associate a commands list to it.
diff --git a/gdb/testsuite/gdb.base/ena-dis-br.exp b/gdb/testsuite/gdb.base/ena-dis-br.exp
index c338a0d51fa9..bf670cbae948 100644
--- a/gdb/testsuite/gdb.base/ena-dis-br.exp
+++ b/gdb/testsuite/gdb.base/ena-dis-br.exp
@@ -295,13 +295,17 @@  gdb_test "continue 2" \
 gdb_test "next" ".*$bp_location11\[ \t\]*marker1.*" \
     "step after continue with ignore count"
 
-set test "continue with ignore count, not stopped at bpt"
-gdb_test_multiple "continue 2" "$test" {
-    -re "Not stopped at any breakpoint; argument ignored.*$gdb_prompt $" {
-	pass "$test"
-    }
-    -re "No breakpoint number -1.*$gdb_prompt $" {
-	kfail gdb/1689 "$test"
+# Application is expected to reach an exit() here, so this can't be run if exit
+# is not working.
+if [exit_is_reliable] {
+    set test "continue with ignore count, not stopped at bpt"
+    gdb_test_multiple "continue 2" "$test" {
+	-re "Not stopped at any breakpoint; argument ignored.*$gdb_prompt $" {
+	    pass "$test"
+	}
+	-re "No breakpoint number -1.*$gdb_prompt $" {
+	    kfail gdb/1689 "$test"
+	}
     }
 }
 
diff --git a/gdb/testsuite/gdb.base/hook-stop.exp b/gdb/testsuite/gdb.base/hook-stop.exp
index 6b49e39b7380..c9bc3d3b6438 100644
--- a/gdb/testsuite/gdb.base/hook-stop.exp
+++ b/gdb/testsuite/gdb.base/hook-stop.exp
@@ -165,5 +165,15 @@  proc hook_stop_next {} {
 hook_stop_before_frame
 hook_stop_kill
 hook_stop_continue_fg
-hook_stop_continue_bg
+
+# Tests that run in background will not run properly with targets that
+# doesn't have a proper "exit" function. For example, this particular
+# test expects that after hook will resume inferior in background, there
+# would be a message "exited normally", however such a message will
+# appear only for targets with a proper # exit(), while others will, for
+# example, spin in the infinite loop.
+if [exit_is_reliable] {
+    hook_stop_continue_bg
+}
+
 hook_stop_next
diff --git a/gdb/testsuite/gdb.base/nextoverexit.exp b/gdb/testsuite/gdb.base/nextoverexit.exp
index 30eafef675ff..fcea35762b00 100644
--- a/gdb/testsuite/gdb.base/nextoverexit.exp
+++ b/gdb/testsuite/gdb.base/nextoverexit.exp
@@ -14,6 +14,13 @@ 
 
 standard_testfile
 
+# This tests expects message "inferior exited normally", which is present only
+# when exit() actually halts the target.
+if ![exit_is_reliable] {
+    unsupported "Function exit() is not reliable on this board."
+    return 0
+}
+
 if {[prepare_for_testing "failed to prepare" $testfile $testfile.c]} {
     return -1
 }
diff --git a/gdb/testsuite/gdb.mi/mi-break.exp b/gdb/testsuite/gdb.mi/mi-break.exp
index 1149bb34c8dc..acec246f52ee 100644
--- a/gdb/testsuite/gdb.mi/mi-break.exp
+++ b/gdb/testsuite/gdb.mi/mi-break.exp
@@ -244,6 +244,11 @@  proc test_disabled_creation {} {
 proc test_breakpoint_commands {} {
     global line_callee2_body
 
+    if ![exit_is_reliable] {
+	unsupported "This test requires working exit() function."
+	return 0
+    }
+
     set bp_no_script \
 	[mi_create_breakpoint "basics.c:callee2" \
 	     "breakpoint commands: insert breakpoint at basics.c:callee2" \
diff --git a/gdb/testsuite/gdb.mi/mi-exit-code.exp b/gdb/testsuite/gdb.mi/mi-exit-code.exp
index f10b49cee0f8..fb5c693597da 100644
--- a/gdb/testsuite/gdb.mi/mi-exit-code.exp
+++ b/gdb/testsuite/gdb.mi/mi-exit-code.exp
@@ -23,6 +23,11 @@  if [mi_gdb_start] {
 
 standard_testfile
 
+if ![exit_is_reliable] {
+    unsupported "Function exit() is not reliable on this board."
+    return 0
+}
+
 if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
     untested "failed to compile"
     return -1
diff --git a/gdb/testsuite/gdb.mi/mi-simplerun.exp b/gdb/testsuite/gdb.mi/mi-simplerun.exp
index 20a079ead896..ce19122803da 100644
--- a/gdb/testsuite/gdb.mi/mi-simplerun.exp
+++ b/gdb/testsuite/gdb.mi/mi-simplerun.exp
@@ -177,6 +177,11 @@  proc test_program_termination {} {
     # -exec-abort
     # (normal termination of inferior)
 
+    if ![exit_is_reliable] {
+	unsupported "Function exit() is not reliable on this board."
+	return
+    }
+
     mi_execute_to "exec-continue" "exited-normally" "" "" "" "" "" "continue to end"
 }