While the previous commit made "p method()::static_var" (no
single-quotes) Just Work, if users (or frontends) try wrapping the
expression with quotes, they'll get:
(gdb) p 'S::method()::static_var'
'S::method()::static_var' has unknown type; cast it to its declared type
even if we _do_ have debug info for that variable. That's better than
the bogus/confusing value what GDB would print before the
stop-assuming-int patch:
(gdb) p 'S::method()::static_var'
$1 = 1
but I think it'd still be nice to make this case Just Work too.
In this case, due to the quoting, the C/C++ parser (c-exp.y)
interprets the whole expression/string as a single symbol name, and we
end up calling lookup_symbol on that name. There's no debug symbol
with that fully-qualified name, but since the compiler gives the
static variable a mangled linkage name exactly like the above, it
appears in the mininal symbols:
$ nm -A local-static | c++filt | grep static_var
local-static:0000000000601040 d S::method()::static_var
... and that's what GDB happens to find/print. This only happens in
C++, note, since for C the compiler uses different linkage names:
local-static-c:0000000000601040 d static_var.1848
So while (in C++, not C) function local static variables are given a
mangled name that demangles to the same syntax that GDB
documents/expects as the way to access function local statics, there's
no global symbol in the debug info with that name at all. The debug
info for a static local variable for a non-inline function looks like
this:
<1><2a1>: Abbrev Number: 19 (DW_TAG_subprogram)
...
<2><2f7>: Abbrev Number: 20 (DW_TAG_variable)
<2f8> DW_AT_name : (indirect string, offset: 0x4e9): static_var
<2fc> DW_AT_decl_file : 1
<2fd> DW_AT_decl_line : 64
<2fe> DW_AT_type : <0x25>
<302> DW_AT_location : 9 byte block: 3 40 10 60 0 0 0 0 0 (DW_OP_addr: 601040)
and for an inline function, it looks like this (linkage name run
through c++filt for convenience):
<2><21b>: Abbrev Number: 16 (DW_TAG_variable)
<21c> DW_AT_name : (indirect string, offset: 0x21a): static_var
<220> DW_AT_decl_file : 1
<221> DW_AT_decl_line : 48
<222> DW_AT_linkage_name: (indirect string, offset: 0x200): S::inline_method()::static_var
<226> DW_AT_type : <0x25>
<22a> DW_AT_external : 1
<22a> DW_AT_location : 9 byte block: 3 a0 10 60 0 0 0 0 0 (DW_OP_addr: 6010a0)
(The inline case makes the variable external so that the linker can
merge the different inlined copies. It seems like GCC never outputs
the linkage name for non-extern globals.)
When we read the DWARF, we record the static_var variable as a regular
variable of the containing function's block. This makes stopping in
the function and printing the variable as usual. The variable just so
happens to have a memory address as location.
So one way to make "p 'S::method()::static_var'" work would be to
record _two_ copies of the symbols for these variables. One in the
function's scope/block, with "static_var" as name, as we currently do,
and another in the static or global blocks (depending on whether the
symbol is external), with a fully-qualified name. I wrote a prototype
patch for that, and it works. For the non-inline case above, since
the debug info doesn't point to the linkage same, that patch built the
physname of the static local variable as the concat of the physname of
the containing function, plus "::", plus the variable's name. We
could make that approach work for C too, though it kind of feels
awkward to record fake symbol names like that in C.
The other approach I tried is to change the C++ symbol lookup routines
instead. This is the approach this commit takes. We can already
lookup up symbol in namespaces and classes, so this feels like a good
fit, and was easy enough. The advantage is that this doesn't require
recording extra symbols.
The test in gdb.cp/m-static.exp that exposed the need for this is
removed, since the same functionality is now covered by
gdb.cp/local-static.exp.
gdb/ChangeLog:
2017-09-04 Pedro Alves <palves@redhat.com>
* cp-namespace.c (cp_search_static_and_baseclasses): Handle
function/method scopes; lookup the nested name as a function local
static variable.
gdb/testsuite/ChangeLog:
2017-09-04 Pedro Alves <palves@redhat.com>
* gdb.base/local-static.exp: Also test with
class::method::variable wholly quoted.
* gdb.cp/m-static.exp (class::method::variable): Remove test.
This commit makes "print S::method()::static_var" actually find the
debug symbol for static_var. Currently, you get:
(gdb) print S::method()::static_var
A syntax error in expression, near `'.
Quoting the whole string would seemingly work before the previous
patch that made GDB stop assuming int for no-debug-info variables:
(gdb) p 'S::method()::static_var'
$1 = 1
... except that's incorrect output, because:
(gdb) ptype 'S::method()::static_var'
type = <data variable, no debug info>
The way to make it work correctly currently is by quoting the
function/method part, like this:
(gdb) print 'S::method()'::static_var
$1 = {i1 = 1, i2 = 2, i3 = 3}
(gdb) ptype 'S::method()'::static_var
type = struct aggregate {
int i1;
int i2;
int i3;
}
At least after the "stop assuming int" patch, this is what we
now get:
(gdb) p 'S::method()::static_var'
'S::method()::static_var' has unknown type; cast it to its declared type
(gdb) p (struct aggregate) 'S::method()::static_var'
$1 = {i1 = 1, i2 = 2, i3 = 3}
However, IMO, users shouldn't really have to care about any of this.
GDB should Just Work, without quoting, IMO.
So here's a patch that implements support for that in the C++ parser.
With this patch, you now get:
(gdb) p S::method()::S_M_s_var_aggregate
$1 = {i1 = 1, i2 = 2, i3 = 3}
(gdb) ptype S::method()::S_M_s_var_aggregate
type = struct aggregate {
int i1;
int i2;
int i3;
}
gdb/ChangeLog:
2017-09-04 Pedro Alves <palves@redhat.com>
(%type <voidval>): Add function_method.
* c-exp.y (exp): New production for calls with no arguments.
(function_method, function_method_void_or_typelist): New
productions.
(exp): New production for "method()::static_var".
* eval.c (evaluate_subexp_standard): Handle OP_FUNC_STATIC_VAR.
* expprint.c (print_subexp_standard, dump_subexp_body_standard):
Handle OP_FUNC_STATIC_VAR.
* parse.c (operator_length_standard):
Handle OP_FUNC_STATIC_VAR.
* std-operator.def (OP_FUNC_STATIC_VAR): New.
gdb/testsuite/ChangeLog:
2017-09-04 Pedro Alves <palves@redhat.com>
* gdb.base/local-static.c: New.
* gdb.base/local-static.cc: New.
* gdb.base/local-static.exp: New.
Since minsym references now go via OP_VAR_MSYM_VALUE, UNOP_MEMVAL_TLS
is no longer used anywhere.
gdb/ChangeLog:
2017-09-04 Pedro Alves <palves@redhat.com>
* eval.c (evaluate_subexp_standard): Remove UNOP_MEMVAL_TLS
handling.
* expprint.c (print_subexp_standard, dump_subexp_body_standard):
Ditto.
* parse.c (operator_length_standard, operator_check_standard):
Ditto.
* std-operator.def (UNOP_MEMVAL_TLS): Delete.
The previous patch left GDB with an inconsistency. While with normal
expression evaluation the "unknown return type" error shows the name
of the function that misses debug info:
(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 commit is a step toward fixing it.
The problem is that while evaluating the expression above, we have no
reference to the minimal symbol where we could extract the name from.
This is because the resulting expression tree has no reference to the
minsym at all. During parsing, the type and address of the minsym are
extracted and an UNOP_MEMVAL / UNOP_MEMVAL_TLS operator is generated
(see write_exp_elt_msym). With "set debug expression", here's what
you see:
0 OP_FUNCALL Number of args: 0
3 UNOP_MEMVAL Type @0x565334a51930 (<text variable, no debug info>)
6 OP_LONG Type @0x565334a51c60 (__CORE_ADDR), value 140737345035648 (0x7ffff7751d80)
The "print" case finds the function name, because
call_function_by_hand looks up the function by address again.
However, for "ptype", we don't reach that code, because obviously we
don't really call the function.
Unlike minsym references, references to variables with debug info have
a pointer to the variable's symbol in the expression tree, with
OP_VAR_VALUE:
(gdb) ptype main()
...
0 OP_FUNCALL Number of args: 0
3 OP_VAR_VALUE Block @0x0, symbol @0x559bbbd9b358 (main(int, char**))
...
so I don't see why do minsyms need to be different. So to prepare for
fixing the missing function name issue, this commit adds a new
OP_VAR_MSYM_VALUE operator that mimics OP_VAR_VALUE, except that it's
for minsyms instead of debug symbols. For infcalls, we now get
expressions like these:
0 OP_FUNCALL Number of args: 0
3 OP_VAR_MSYM_VALUE Objfile @0x1e41bf0, msymbol @0x7fffe599b000 (getenv)
In the following patch, we'll make OP_FUNCALL extract the function
name from the symbol stored in OP_VAR_VALUE/OP_VAR_MSYM_VALUE.
OP_VAR_MSYM_VALUE will be used more in a later patch in the series
too.
gdb/ChangeLog:
2017-09-04 Pedro Alves <palves@redhat.com>
* ada-lang.c (resolve_subexp): Handle OP_VAR_MSYM_VALUE.
* ax-gdb.c (gen_msym_var_ref): New function.
(gen_expr): Handle OP_VAR_MSYM_VALUE.
* eval.c (evaluate_var_msym_value): New function.
* eval.c (evaluate_subexp_standard): Handle OP_VAR_MSYM_VALUE.
<OP_FUNCALL>: Extract function name from symbol/minsym and pass it
to call_function_by_hand.
* expprint.c (print_subexp_standard, dump_subexp_body_standard):
Handle OP_VAR_MSYM_VALUE.
(union exp_element) <msymbol>: New field.
* minsyms.h (struct type): Forward declare.
(find_minsym_type_and_address): Declare.
* parse.c (write_exp_elt_msym): New function.
(write_exp_msymbol): Delete, refactored as ...
(find_minsym_type_and_address): ... this new function.
(write_exp_msymbol): Reimplement using OP_VAR_MSYM_VALUE.
(operator_length_standard, operator_check_standard): Handle
OP_VAR_MSYM_VALUE.
* std-operator.def (OP_VAR_MSYM_VALUE): New.
This applies the second part of GDB's End of Year Procedure, which
updates the copyright year range in all of GDB's files.
gdb/ChangeLog:
Update copyright year range in all GDB files.
TERNOP_SLICE was added for language Chill, but it is used for Ada and D later.
Since language Chill was removed from GDB, TERNOP_SLICE is only used for
Ada and D. This patch is to update its comments.
gdb:
2014-07-20 Yao Qi <yao@codesourcery.com>
* std-operator.def: Update comments to TERNOP_SLICE.
BINOP_RANGE was added by the following commit for chill language.
commit badefd2800
Author: Per Bothner <per@bothner.com>
Date: Wed Nov 29 22:59:31 1995 +0000
* expression.h (enum exp_opcode): Add BINOP_RANGE.
* expprint.c (dump_expression): Support BINOP_RANGE.
* eval.c (evaluate_subexp_standard): Handle BINOP_RANGE (as error).
(case MULTI_SUBSCRIPT): Fix broken f77 value->int ad hoc conversion.
* ch-lang.c (chill_op_print_tab): Support BINOP_RANGE.
(evaluate_subexp_chill): Error on BINOP_COMMA.
Chill language is no longer supported, so we can remove BINOP_RANGE too.
This patch is to remove BINOP_RANGE.
gdb:
2014-07-20 Yao Qi <yao@codesourcery.com>
* std-operator.def: Remove BINOP_RANGE.
* breakpoint.c (watchpoint_exp_is_const): Update.
* expprint.c (dump_subexp_body_standard): Likewise.
* eval.c (init_array_element): Remove dead code.
(evaluate_subexp_standard): Likewise.
Chill language support was removed several years ago, and BINOP_IN
isn't used for Pascal. This patch is to remove BINOP_IN.
gdb:
2014-07-20 Yao Qi <yao@codesourcery.com>
* std-operator.def: Remove BINOP_IN.
* breakpoint.c (watchpoint_exp_is_const): Update.
* eval.c (evaluate_subexp_standard): Likewise.
* expprint.c (dump_subexp_body_standard): Likewise.
Two modifications:
1. The addition of 2013 to the copyright year range for every file;
2. The use of a single year range, instead of potentially multiple
year ranges, as approved by the FSF.
Fix debug printing of BINOP_IN, OP_OBJC_MSGCALL,
OP_F77_UNDETERMINED_ARGLIST, OP_COMPLEX, OP_OBJC_SELECTOR, OP_NAME,
OP_OBJC_NSSTRING, OP_F90_RANGE and OP_DECFLOAT.
* ada-operator.inc: Rename the file to ...
* ada-operator.def: ... here, wrap all the entries by macro OP.
* expprint.c (op_name_standard): Remove all the entries. Include
"std-operator.def" instead.
* expression.h (enum exp_opcode): Include "std-operator.def" and
"ada-operator.def". Move all the entries ...
* std-operator.def: ... here, wrap all the entries by macro OP.