The fact that GDB defaults to assuming that functions return int, when
it has no debug info for the function has been a recurring source of
user confusion. Recently this came up on the errno pretty printer
discussions. Shortly after, it came up again on IRC, with someone
wondering why does getenv() in GDB return a negative int:
(gdb) p getenv("PATH")
$1 = -6185
This question (with s/getenv/random-other-C-runtime-function) is a FAQ
on IRC.
The reason for the above is:
(gdb) p getenv
$2 = {<text variable, no debug info>} 0x7ffff7751d80 <getenv>
(gdb) ptype getenv
type = int ()
... which means that GDB truncated the 64-bit pointer that is actually
returned from getent to 32-bit, and then sign-extended it:
(gdb) p /x -6185
$6 = 0xffffe7d7
The workaround is to cast the function to the right type, like:
(gdb) p ((char *(*) (const char *)) getenv) ("PATH")
$3 = 0x7fffffffe7d7 "/usr/local/bin:/"...
IMO, we should do better than this.
I see the "assume-int" issue the same way I see printing bogus values
for optimized-out variables instead of "<optimized out>" -- I'd much
rather that the debugger tells me "I don't know" and tells me how to
fix it than showing me bogus misleading results, making me go around
tilting at windmills.
If GDB prints a signed integer when you're expecting a pointer or
aggregate, you at least have some sense that something is off, but
consider the case of the function actually returning a 64-bit integer.
For example, compile this without debug info:
unsigned long long
function ()
{
return 0x7fffffffffffffff;
}
Currently, with pristine GDB, you get:
(gdb) p function ()
$1 = -1 # incorrect
(gdb) p /x function ()
$2 = 0xffffffff # incorrect
maybe after spending a few hours debugging you suspect something is
wrong with that -1, and do:
(gdb) ptype function
type = int ()
and maybe, just maybe, you realize that the function actually returns
unsigned long long. And you try to fix it with:
(gdb) p /x (unsigned long long) function ()
$3 = 0xffffffffffffffff # incorrect
... which still produces the wrong result, because GDB simply applied
int to unsigned long long conversion. Meaning, it sign-extended the
integer that it extracted from the return of the function, to 64-bits.
and then maybe, after asking around on IRC, you realize you have to
cast the function to a pointer of the right type, and call that. It
won't be easy, but after a few missteps, you'll get to it:
..... (gdb) p /x ((unsigned long long(*) ()) function) ()
$666 = 0x7fffffffffffffff # finally! :-)
So to improve on the user experience, this patch does the following
(interrelated) things:
- makes no-debug-info functions no longer default to "int" as return
type. Instead, they're left with NULL/"<unknown return type>"
return type.
(gdb) ptype getenv
type = <unknown return type> ()
- makes calling a function with unknown return type an error.
(gdb) p getenv ("PATH")
'getenv' has unknown return type; cast the call to its declared return type
- and then to make it easier to call the function, makes it possible
to _only_ cast the return of the function to the right type,
instead of having to cast the function to a function pointer:
(gdb) p (char *) getenv ("PATH") # now Just Works
$3 = 0x7fffffffe7d7 "/usr/local/bin:/"...
(gdb) p ((char *(*) (const char *)) getenv) ("PATH") # continues working
$4 = 0x7fffffffe7d7 "/usr/local/bin:/"...
I.e., it makes GDB default the function's return type to the type
of the cast, and the function's parameters to the type of the
arguments passed down.
After this patch, here's what you'll get for the "unsigned long long"
example above:
(gdb) p function ()
'function' has unknown return type; cast the call to its declared return type
(gdb) p /x (unsigned long long) function ()
$4 = 0x7fffffffffffffff # correct!
Note that while with "print" GDB shows the name of the function that
has the problem:
(gdb) p getenv ("PATH")
'getenv' has unknown return type; cast the call to its declared return type
which can by handy in more complicated expressions, "ptype" does not:
(gdb) ptype getenv ("PATH")
function has unknown return type; cast the call to its declared return type
This will be fixed in the next patch.
gdb/ChangeLog:
2017-09-04 Pedro Alves <palves@redhat.com>
* ada-lang.c (ada_evaluate_subexp) <TYPE_CODE_FUNC>: Don't handle
TYPE_GNU_IFUNC specially here. Throw error if return type is
unknown.
* ada-typeprint.c (print_func_type): Handle functions with unknown
return type.
* c-typeprint.c (c_type_print_base): Handle functions and methods
with unknown return type.
* compile/compile-c-symbols.c (convert_symbol_bmsym)
<mst_text_gnu_ifunc>: Use nodebug_text_gnu_ifunc_symbol.
* compile/compile-c-types.c: Include "objfiles.h".
(convert_func): For functions with unknown return type, warn and
default to int.
* compile/compile-object-run.c (compile_object_run): Adjust call
to call_function_by_hand_dummy.
* elfread.c (elf_gnu_ifunc_resolve_addr): Adjust call to
call_function_by_hand.
* eval.c (evaluate_subexp_standard): Adjust calls to
call_function_by_hand. Handle functions and methods with unknown
return type. Pass expect_type to call_function_by_hand.
* f-typeprint.c (f_type_print_base): Handle functions with unknown
return type.
* gcore.c (call_target_sbrk): Adjust call to
call_function_by_hand.
* gdbtypes.c (objfile_type): Leave nodebug text symbol with NULL
return type instead of int. Make nodebug_text_gnu_ifunc_symbol be
an integer address type instead of nodebug.
* guile/scm-value.c (gdbscm_value_call): Adjust call to
call_function_by_hand.
* infcall.c (error_call_unknown_return_type): New function.
(call_function_by_hand): New "default_return_type" parameter.
Pass it down.
(call_function_by_hand_dummy): New "default_return_type"
parameter. Use it instead of defaulting to int. If there's no
default and the return type is unknown, throw an error. If
there's a default return type, and the called function has no
debug info, then assume the function is prototyped.
* infcall.h (call_function_by_hand, call_function_by_hand_dummy):
New "default_return_type" parameter.
(error_call_unknown_return_type): New declaration.
* linux-fork.c (call_lseek): Cast return type of lseek.
(inferior_call_waitpid, checkpoint_command): Adjust calls to
call_function_by_hand.
* linux-tdep.c (linux_infcall_mmap, linux_infcall_munmap): Adjust
calls to call_function_by_hand.
* m2-typeprint.c (m2_procedure): Handle functions with unknown
return type.
* objc-lang.c (lookup_objc_class, lookup_child_selector)
(value_nsstring, print_object_command): Adjust calls to
call_function_by_hand.
* p-typeprint.c (pascal_type_print_varspec_prefix): Handle
functions with unknown return type.
(pascal_type_print_func_varspec_suffix): New function.
(pascal_type_print_varspec_suffix) <TYPE_CODE_FUNC,
TYPE_CODE_METHOD>: Use it.
* python/py-value.c (valpy_call): Adjust call to
call_function_by_hand.
* rust-lang.c (rust_evaluate_funcall): Adjust call to
call_function_by_hand.
* valarith.c (value_x_binop, value_x_unop): Adjust calls to
call_function_by_hand.
* valops.c (value_allocate_space_in_inferior): Adjust call to
call_function_by_hand.
* typeprint.c (type_print_unknown_return_type): New function.
* typeprint.h (type_print_unknown_return_type): New declaration.
gdb/testsuite/ChangeLog:
2017-09-04 Pedro Alves <palves@redhat.com>
* gdb.base/break-main-file-remove-fail.exp (test_remove_bp): Cast
return type of munmap in infcall.
* gdb.base/break-probes.exp: Cast return type of foo in infcall.
* gdb.base/checkpoint.exp: Simplify using for loop. Cast return
type of ftell in infcall.
* gdb.base/dprintf-detach.exp (dprintf_detach_test): Cast return
type of getpid in infcall.
* gdb.base/infcall-exec.exp: Cast return type of execlp in
infcall.
* gdb.base/info-os.exp: Cast return type of getpid in infcall.
Bail on failure to extract the pid.
* gdb.base/nodebug.c: #include <stdint.h>.
(multf, multf_noproto, mult, mult_noproto, add8, add8_noproto):
New functions.
* gdb.base/nodebug.exp (test_call_promotion): New procedure.
Change expected output of print/whatis/ptype with functions with
no debug info. Test all supported languages. Call
test_call_promotion.
* gdb.compile/compile.exp: Adjust expected output to expect
warning.
* gdb.threads/siginfo-threads.exp: Likewise.
387 lines
13 KiB
Plaintext
387 lines
13 KiB
Plaintext
# Copyright 2014-2017 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" \
|
|
"\r\n#0 \[^\r\n\]* in _gdb_expr \[^\r\n\]*\r\n#1 <function called from gdb>\r\n.*"
|
|
|
|
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 \\+ 5 \\* I"
|
|
|
|
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 "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" "Unknown argument.*"
|
|
|
|
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 with the raw option set.*" \
|
|
"Test compile file and raw option without a filename"
|
|
gdb_test "compile file -z" \
|
|
"Unknown argument.*" \
|
|
"test compile file with unknown argument"
|
|
|
|
|
|
# LOC_CONST tests.
|
|
|
|
if { $srcfile3 != "" } {
|
|
gdb_test "p constvar" " = 3"
|
|
gdb_test "info addr constvar" {Symbol "constvar" is constant\.}
|
|
|
|
gdb_test "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"
|