| # Copyright 2014-2021 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/>. |
| |
| standard_testfile .c compile-shlib.c compile-constvar.S compile-nodebug.c |
| |
| get_compiler_info |
| set options {} |
| if [test_compiler_info gcc*] { |
| lappend options additional_flags=-g3 |
| } |
| |
| if { ![istarget x86_64-*-* ] || ![is_lp64_target] } { |
| verbose "Skipping x86_64 LOC_CONST test." |
| set srcfile3 "" |
| } |
| |
| set srcfilesoptions [list ${srcfile} ${options}] |
| if { $srcfile3 != "" } { |
| lappend srcfilesoptions $srcfile3 ${options} |
| } |
| lappend srcfilesoptions $srcfile4 "nodebug" |
| if { [eval build_executable_from_specs ${testfile}.exp $testfile {$options} ${srcfilesoptions}] } { |
| return -1 |
| } |
| |
| clean_restart ${testfile} |
| |
| # |
| # Test command without an running inferior. |
| # |
| gdb_test "compile code int i=2;" \ |
| "The program must be running for the compile command to work.*" \ |
| "test compile code command without running inferior" |
| |
| gdb_test "compile int i=2;" \ |
| "The program must be running for the compile command to work.*" \ |
| "test compile command without running inferior" |
| |
| gdb_test "compile file -r ${srcdir}/${subdir}/${testfile}-mod.c" \ |
| "The program must be running for the compile command to work.*" \ |
| "test compile file command without running inferior" |
| |
| if ![runto_main] { |
| return -1 |
| } |
| |
| if {[skip_compile_feature_tests]} { |
| untested "compile command not supported (could not find libcc1 shared library?)" |
| return -1 |
| } |
| |
| # |
| # Test delimiter for code, and arguments. |
| # |
| |
| gdb_test_no_output "compile -- f = 10" \ |
| "test abbreviations and code delimiter" |
| |
| gdb_test "compile f = 10;" ".*= 10;: No such file.*" \ |
| "Test abbreviations and code collision" |
| |
| gdb_test_no_output "compile -r -- void _gdb_expr(){int i = 5;}" \ |
| "test delimiter with -r" |
| |
| gdb_test_no_output "compile -raw -- void _gdb_expr(){int i = 5;}" \ |
| "test delimiter with -raw" |
| |
| gdb_test "compile -- -r void _gdb_expr(){int i = 5;}" \ |
| ".* error: 'r' undeclared \\(first use in this function\\).*" \ |
| "test delimiter with -r after it" |
| |
| gdb_test "p globalvar" " = 10" "expect 10" |
| |
| gdb_test_no_output "compile code globalvar = 11" \ |
| "set variable without trailing semicolon" |
| gdb_test "p globalvar" " = 11" "check variable without trailing semicolon" |
| |
| gdb_test_no_output "compile code globalvar = SOME_MACRO;" \ |
| "set variable from macro" |
| gdb_test "p globalvar" " = 23" "expect 23" |
| |
| gdb_test_no_output "compile code globalvar = ARG_MACRO(0, 0);" \ |
| "set variable from function-like macro" |
| gdb_test "p globalvar" " = -1" "expect -1" |
| |
| gdb_test_no_output "compile code globalvar = 42;" "set variable" |
| gdb_test "p globalvar" " = 42" "expect 42" |
| |
| gdb_test_no_output "compile code globalvar *= 2;" "modify variable" |
| gdb_test "p globalvar" " = 84" "expect 84" |
| |
| gdb_test_multiple "compile code" "compile code multiline 1" { -re "\r\n>$" {} } |
| gdb_test_multiple "globalvar = 10;" "compile code multiline 2" { -re "\r\n>$" {} } |
| gdb_test_multiple "globalvar *= 2;" "compile code multiline 3" { -re "\r\n>$" {} } |
| gdb_test_no_output "end" "compile code multiline 4" |
| gdb_test "p globalvar" " = 20" "expect 20" |
| |
| gdb_test_no_output "compile file -r ${srcdir}/${subdir}/${testfile}-mod.c" \ |
| "use external source file" |
| gdb_test "p globalvar" " = 7" "expect 7" |
| |
| gdb_test_no_output "compile code func_static (2);" "call static function" |
| gdb_test "p globalvar" " = 9" "expect 9" |
| gdb_test_no_output "compile code func_global (1);" "call global function" |
| gdb_test "p globalvar" " = 8" "expect 8" |
| |
| gdb_test_no_output \ |
| "compile code globalvar = (sizeof (ulonger) == sizeof (long))" \ |
| "compute size of ulonger" |
| gdb_test "p globalvar" " = 1" "check size of ulonger" |
| gdb_test_no_output \ |
| "compile code globalvar = (sizeof (longer) == sizeof (long))" \ |
| "compute size of longer" |
| gdb_test "p globalvar" " = 1" "check size of longer" |
| gdb_test_no_output "compile code globalvar = MINUS_1" |
| gdb_test "p globalvar" " = -1" "check MINUS_1" |
| |
| gdb_test_no_output "compile code globalvar = static_local" |
| gdb_test "p globalvar" " = 77000" "check static_local" |
| |
| gdb_test_no_output "compile code static int staticvar = 5; intptr = &staticvar" \ |
| "do not keep jit in memory" |
| gdb_test "p *intptr" "Cannot access memory at address 0x\[0-9a-f\]+" "expect no 5" |
| |
| gdb_test "compile code func_doesnotexist ();" "warning: Could not find symbol \"func_doesnotexist\" for .*" |
| |
| gdb_test "compile code *(volatile int *) 0 = 0;" \ |
| "The program being debugged was signaled while in a function called from GDB\\.\r\nGDB remains in the frame where the signal was received\\.\r\n.*" \ |
| "compile code segfault first" |
| gdb_test "bt" [multi_line \ |
| "#0 ($hex in )?_gdb_expr .*" \ |
| "#1 <function called from gdb>" \ |
| "#2 .*" \ |
| ] |
| |
| set test "p/x \$pc" |
| set infcall_pc 0 |
| gdb_test_multiple $test $test { |
| -re " = (0x\[0-9a-f\]+)\r\n$gdb_prompt $" { |
| set infcall_pc $expect_out(1,string) |
| pass $test |
| } |
| } |
| |
| gdb_test "info sym $infcall_pc" "\r\n_gdb_expr .*" "info sym found" |
| gdb_test "return" "\r\n#0 main .*" "return" \ |
| "Make _gdb_expr return now\\? \\(y or n\\) " "y" |
| gdb_test "info sym $infcall_pc" "\r\nNo symbol matches .*" "info sym not found" |
| |
| gdb_test_no_output "set unwindonsignal on" |
| gdb_test "compile code *(volatile int *) 0 = 0;" \ |
| "The program being debugged was signaled while in a function called from GDB\\.\r\nGDB has restored the context to what it was before the call\\.\r\n.*" \ |
| "compile code segfault second" |
| |
| gdb_breakpoint [gdb_get_line_number "break-here"] |
| gdb_continue_to_breakpoint "break-here" ".* break-here .*" |
| |
| gdb_test "p localvar" " = 50" "expect localvar 50" |
| |
| gdb_test_no_output "compile code localvar = 12;" "set localvar" |
| gdb_test "p localvar" " = 12" "expect 12" |
| |
| gdb_test_no_output "compile code localvar *= 2;" "modify localvar" |
| gdb_test "p localvar" " = 24" "expect 24" |
| |
| gdb_test_no_output "compile code localvar = shadowed" \ |
| "test shadowing" |
| gdb_test "p localvar" " = 52" "expect 52" |
| |
| gdb_test_no_output "compile code localvar = externed" |
| gdb_test "p localvar" " = 7" "test extern in inner scope" |
| |
| gdb_test_no_output "compile code vla\[2\] = 7" |
| gdb_test "p vla\[2\]" " = 7" |
| gdb_test_no_output \ |
| "compile code localvar = (sizeof (vla) == bound * sizeof (vla\[0\]))" |
| gdb_test "p localvar" " = 1" |
| |
| # |
| # Test setting fields and also many different types. |
| # |
| |
| set skip_struct_object 0 |
| set test "compile code struct_object.selffield = &struct_object" |
| gdb_test_multiple $test $test { |
| -re "^$test\r\n$gdb_prompt $" { |
| pass "$test" |
| } |
| -re " error: Unexpected type id from GCC, check you use recent enough GCC\\.\r\n.*\r\n$gdb_prompt $" { |
| xfail "$test (PR compile/18202)" |
| |
| # All following tests will break with the same error message. |
| set skip_struct_object 1 |
| } |
| } |
| |
| if {$skip_struct_object} { |
| untested "all struct_object tests" |
| } else { |
| gdb_test "print struct_object.selffield == &struct_object" " = 1" |
| |
| gdb_test_no_output "compile code struct_object.charfield = 1" |
| gdb_test "print struct_object.charfield" " = 1 '\\\\001'" |
| gdb_test_no_output "compile code struct_object.ucharfield = 1" |
| gdb_test "print struct_object.ucharfield" " = 1 '\\\\001'" |
| |
| foreach {field value} { |
| shortfield -5 |
| ushortfield 5 |
| intfield -7 |
| uintfield 7 |
| bitfield 2 |
| longfield -9 |
| ulongfield 9 |
| enumfield ONE |
| floatfield 1 |
| doublefield 2 |
| } { |
| gdb_test_no_output "compile code struct_object.$field = $value" |
| gdb_test "print struct_object.$field" " = $value" |
| } |
| |
| gdb_test_no_output "compile code struct_object.arrayfield\[2\] = 7" |
| gdb_test "print struct_object.arrayfield" \ |
| " = \\{0, 0, 7, 0, 0\\}" |
| |
| gdb_test_no_output "compile code struct_object.complexfield = 7 + 5i" |
| gdb_test "print struct_object.complexfield" " = 7 \\+ 5i" |
| |
| gdb_test_no_output "compile code struct_object.boolfield = 1" |
| gdb_test "print struct_object.boolfield" " = true" |
| |
| gdb_test_no_output "compile code struct_object.vectorfield\[2\] = 7" |
| gdb_test "print struct_object.vectorfield" \ |
| " = \\{0, 0, 7, 0\\}" |
| |
| } |
| |
| gdb_test_no_output "compile code union_object.typedeffield = 7" |
| gdb_test "print union_object.typedeffield" " = 7" |
| gdb_test "print union_object.intfield" " = 7" |
| |
| |
| # LOC_UNRESOLVED tests. |
| |
| gdb_test "print unresolved" " = 20" |
| gdb_test_no_output "compile code globalvar = unresolved;" |
| gdb_test "print globalvar" " = 20" "print unresolved value" |
| |
| # Test shadowing with global and static variables. |
| |
| gdb_test_no_output "compile code globalshadow += 1;" |
| gdb_test "print globalshadow" " = 101" |
| gdb_test_no_output "compile code extern int globalshadow; globalshadow += 5;" |
| gdb_test "print 'compile.c'::globalshadow" " = 15" |
| gdb_test "print globalshadow" " = 101" "print globalshadow second time" |
| gdb_test_no_output "compile code staticshadow += 2;" |
| gdb_test "print staticshadow" " = 202" |
| # "extern int staticshadow;" cannot access static variable. |
| |
| # Raw code cannot refer to locals. |
| # As it references global variable we need the #pragma. |
| # For #pragma we need multiline input. |
| gdb_test_multiple "compile code -r" "compile code -r multiline 1" { -re "\r\n>$" {} } |
| gdb_test_multiple "#pragma GCC user_expression" "compile code -r multiline 2" { -re "\r\n>$" {} } |
| gdb_test_multiple "void _gdb_expr(void) { globalshadow = 77000; }" "compile code -r multiline 3" { -re "\r\n>$" {} } |
| gdb_test_no_output "end" "compile code -r multiline 4" |
| gdb_test "print 'compile.c'::globalshadow" " = 77000" \ |
| "check globalshadow with -r" |
| |
| # Test GOT vs. resolving jit function pointers. |
| |
| gdb_test_no_output "compile -raw -- int func(){return 21;} void _gdb_expr(){ void abort (void); int (*funcp)()=func; if (funcp()!=21) abort(); }" \ |
| "pointer to jit function" |
| |
| # |
| # Test the case where the registers structure would not normally have |
| # any fields. |
| # |
| |
| gdb_breakpoint [gdb_get_line_number "no_args_or_locals breakpoint"] |
| gdb_continue_to_breakpoint "no_args_or_locals" |
| |
| gdb_test_no_output "compile code globalvar = 77;" "set variable to 77" |
| gdb_test "p globalvar" " = 77" "expect 77" |
| |
| |
| # Test reference to minimal_symbol, not (full) symbol. |
| |
| gdb_test "compile code globalvar = func_nodebug (75);" \ |
| "warning: function has unknown return type; assuming int" \ |
| "call func_nodebug" |
| gdb_test "p globalvar" " = -75" "expect -75" |
| gdb_test \ |
| "compile code int (*funcp) (int) = func_nodebug; globalvar = funcp (76);" \ |
| "warning: function has unknown return type; assuming int" \ |
| "call func_nodebug indirectly" |
| gdb_test "p globalvar" " = -76" "expect -76" |
| |
| |
| # Test compiled module memory protection. |
| |
| gdb_test_no_output "set debug compile on" |
| gdb_test "compile code static const int readonly = 1; *(int *) &readonly = 2;" \ |
| "The program being debugged was signaled while in a function called from GDB\\.\r\nGDB has restored the context to what it was before the call\\.\r\n.*" |
| gdb_test_no_output "set debug compile off" |
| |
| |
| # |
| # Some simple coverage tests. |
| # |
| |
| gdb_test "show debug compile" "Compile debugging is .*" |
| gdb_test "show compile-args" \ |
| "Compile command command-line arguments are .*" |
| gdb_test "compile code -z" "Unrecognized option at: -z" |
| |
| gdb_test "set lang rust" \ |
| "Warning: the current language does not match this frame." |
| gdb_test "compile code globalvar" "No compiler support for language rust\\." |
| gdb_test_no_output "set lang auto" |
| |
| gdb_test_no_output "compile code union union_type newdecl_u" |
| gdb_test_no_output "compile code struct struct_type newdecl_s" |
| gdb_test_no_output "compile code inttypedef newdecl_i" |
| |
| gdb_test "compile file" \ |
| "You must provide a filename for this command.*" \ |
| "Test compile file without a filename" |
| gdb_test "compile file -r" \ |
| "You must provide a filename for this command.*" \ |
| "Test compile file and raw option without a filename" |
| gdb_test "compile file -z" \ |
| "Unrecognized option at: -z" \ |
| "test compile file with unknown option" |
| gdb_test "compile file -z --" \ |
| "Unrecognized option at: -z --" \ |
| "test compile file with unknown option plus --" |
| gdb_test "compile file -raw -- -raw" \ |
| "/-raw: No such file or directory.*" \ |
| "test compile file \"-raw\" file" |
| |
| # LOC_CONST tests. |
| |
| if { $srcfile3 != "" } { |
| gdb_test "p constvar" " = 3" |
| gdb_test "info addr constvar" {Symbol "constvar" is constant\.} |
| |
| gdb_test_no_output "compile code globalvar = constvar;" |
| gdb_test "print globalvar" " = 3" "print constvar value" |
| } else { |
| untested "print constvar value" |
| } |
| |
| # Shared library tests. |
| |
| if {[skip_shlib_tests]} { |
| untested "skipping shlib tests" |
| return; |
| } |
| |
| set libbin [standard_output_file ${testfile}-shlib.so] |
| set binfile [standard_output_file ${testfile}-shlib] |
| |
| if { [gdb_compile_shlib ${srcdir}/${subdir}/${srcfile2} $libbin {debug}] != "" |
| || [gdb_compile ${srcdir}/${subdir}/${srcfile} $binfile executable \ |
| [list debug shlib=$libbin]] == -1 } { |
| return -1 |
| } |
| |
| clean_restart $binfile |
| gdb_load_shlib $libbin |
| |
| if ![runto_main] { |
| return -1 |
| } |
| |
| gdb_test_no_output "compile code shlib_func ();" "call shared library function" |
| gdb_test "p globalvar" " = 1" "expect 1" |
| |
| gdb_test_no_output "compile code shlibvar += 5;" "modify shared library variable" |
| gdb_test "p shlibvar" " = 15" "expect 15" |