aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.cp
AgeCommit message (Collapse)AuthorFilesLines
2021-12-23gdb: on x86-64 non-trivial C++ objects are returned in memoryAndrew Burgess2-1/+44
Fixes PR gdb/28681. It was observed that after using the `finish` command an incorrect value was displayed in some cases. Specifically, this behaviour was observed on an x86-64 target. Consider this test program: struct A { int i; A () { this->i = 0; } A (const A& a) { this->i = a.i; } }; A func (int i) { A a; a.i = i; return a; } int main () { A a = func (3); return a.i; } And this GDB session: $ gdb -q ex.x Reading symbols from ex.x... (gdb) b func Breakpoint 1 at 0x401115: file ex.cc, line 14. (gdb) r Starting program: /home/andrew/tmp/ex.x Breakpoint 1, func (i=3) at ex.cc:14 14 A a; (gdb) finish Run till exit from #0 func (i=3) at ex.cc:14 main () at ex.cc:23 23 return a.i; Value returned is $1 = { i = -19044 } (gdb) p a $2 = { i = 3 } (gdb) Notice how after the `finish` the contents of $1 are junk, but, when I immediately ask for the value of `a`, I get back the correct value. The problem here is that after the finish command GDB calls the function amd64_return_value to figure out where the return value can be found (on x86-64 targets anyway). This function makes the wrong choice for the struct A in our case, as sizeof(A) <= 8, then amd64_return_value decides that A will be returned in a register. GDB then reads the return value register an interprets the contents as an instance of A. Unfortunately, A is not trivially copyable (due to its copy constructor), and the sys-v specification for argument and return value passing, says that any non-trivial C++ object should have space allocated for it by the caller, and the address of this space is passed to the callee as a hidden first argument. The callee should then return the address of this space as the return value. And so, the register that GDB is treating as containing an instance of A, actually contains the address of an instance of A (in this case on the stack), this is why GDB shows the incorrect result. The call stack within GDB for where we actually go wrong is this: amd64_return_value amd64_classify amd64_classify_aggregate And it is in amd64_classify_aggregate that we should be classifying the type as AMD64_MEMORY, instead of as AMD64_INTEGER as we currently do (via a call to amd64_classify_aggregate_field). At the top of amd64_classify_aggregate we already have this logic: if (TYPE_LENGTH (type) > 16 || amd64_has_unaligned_fields (type)) { theclass[0] = theclass[1] = AMD64_MEMORY; return; } Which handles some easy cases where we know a struct will be placed into memory, that is (a) the struct is more than 16-bytes in size, or (b) the struct has any unaligned fields. All we need then, is to add a check here to see if the struct is trivially copyable. If it is not then we know the struct will be passed in memory. I originally structured the code like this: if (TYPE_LENGTH (type) > 16 || amd64_has_unaligned_fields (type) || !language_pass_by_reference (type).trivially_copyable) { theclass[0] = theclass[1] = AMD64_MEMORY; return; } This solved the example from the bug, and my small example above. So then I started adding some more extensive tests to the GDB testsuite, and I ran into a problem. I hit this error: gdbtypes.h:676: internal-error: loc_bitpos: Assertion `m_loc_kind == FIELD_LOC_KIND_BITPOS' failed. This problem is triggered from: amd64_classify_aggregate amd64_has_unaligned_fields field::loc_bitpos Inside the unaligned field check we try to get the bit position of each field. Unfortunately, in some cases the field location is not FIELD_LOC_KIND_BITPOS, but is FIELD_LOC_KIND_DWARF_BLOCK. An example that shows this bug is: struct B { short j; }; struct A : virtual public B { short i; A () { this->i = 0; } A (const A& a) { this->i = a.i; } }; A func (int i) { A a; a.i = i; return a; } int main () { A a = func (3); return a.i; } It is the virtual base class, B, that causes the problem. The base class is represented, within GDB, as a field within A. However, the location type for this field is a DWARF_BLOCK. I spent a little time trying to figure out how to convert the DWARF_BLOCK to a BITPOS, however, I realised that, in this case at least, conversion is not needed. The C++ standard says that a class is not trivially copyable if it has any virtual base classes. And so, in this case, even if I could figure out the BITPOS for the virtual base class fields, I know for sure that I would immediately fail the trivially_copyable check. So, lets just reorder the checks in amd64_classify_aggregate to: if (TYPE_LENGTH (type) > 16 || !language_pass_by_reference (type).trivially_copyable || amd64_has_unaligned_fields (type)) { theclass[0] = theclass[1] = AMD64_MEMORY; return; } Now, if we have a class with virtual bases we will fail quicker, and avoid the unaligned fields check completely. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28681
2021-12-02gdb/testsuite: update tests looking for "DWARF 2" debug formatSimon Marchi2-2/+2
Commit ab557072b8ec ("gdb: use actual DWARF version in compunit's debugformat field") changes the debug format string in "info source" to show the actual DWARF version, rather than always show "DWARF 2". However, it failed to consider that some tests checked for the "DWARF 2" string to see if the test program is compiled with DWARF debug information. Since everything is compiled with DWARF 4 or 5 nowadays, that changed the behavior of those tests. Notably, it prevent the tests using skip_inline_var_tests to run. Grep through the testsuite for "DWARF 2" and change all occurrences I could find to use "DWARF [0-9]" instead (that string is passed to TCL's string match). Change-Id: Ic7fb0217fb9623880c6f155da6becba0f567a885
2021-11-25PR gdb/28480: Improve ambiguous member detectionBruno Larsen2-0/+29
Basic ambiguity detection assumes that when 2 fields with the same name have the same byte offset, it must be an unambiguous request. This is not always correct. Consider the following code: class empty { }; class A { public: [[no_unique_address]] empty e; }; class B { public: int e; }; class C: public A, public B { }; if we tried to use c.e in code, the compiler would warn of an ambiguity, however, since A::e does not demand an unique address, it gets the same address (and thus byte offset) of the members, making A::e and B::e have the same address. however, "print c.e" would fail to report the ambiguity, and would instead print it as an empty class (first path found). The new code solves this by checking for other found_fields that have different m_struct_path.back() (final class that the member was found in), despite having the same byte offset. The testcase gdb.cp/ambiguous.exp was also changed to test for this behavior.
2021-11-19gdb/testsuite: Extend tests for print of cv qualifiersChristina Schimpe2-0/+16
This commit supplements whatis and ptype command tests for print of const-volatile qualifiers. gdb/testsuite/ChangeLog: 2021-11-16 Christina Schimpe <christina.schimpe@intel.com> * gdb.cp/ptype-cv-cp.cc: New const and volatile typedef variables. * gdb.cp/ptype-cv-cp.exp: Add new tests.
2021-11-19gdb: Print cv qualifiers if class attributes are substitutedChristina Schimpe2-0/+50
Make ptype print const/volatile qualifiers when template or typedef attributes are substituted. For a programm like ~~~ template<typename DataT> class Cfoo { typedef float myfloat; public: DataT me0; const DataT me1=1; const myfloat me2=2.0; }; int main() { Cfoo<int> cfoo; return 0; } ~~~ gdb outputs the following type for cfoo's attributes: ~~~ (gdb) b 14 Breakpoint 1 at 0x1170: file tmp.cc, line 14. (gdb) run Starting program: /tmp Breakpoint 1, main () at tmp.cc:14 14 return 0; (gdb) ptype cfoo type = class Cfoo<int> [with DataT = int] { public: DataT me0; DataT me1; myfloat me2; private: typedef float myfloat; } ~~~ The cv qualifiers (const in this case) are ignored for me1 and me2. After: ~~~ (gdb) ptype cfoo type = class Cfoo<int> [with DataT = int] { public: DataT me0; const DataT me1; const myfloat me2; private: typedef float myfloat; } ~~~ gdb/ChangeLog: 2021-11-16 Christina Schimpe <christina.schimpe@intel.com> * gdb/c-typeprint.c: Print cv qualifiers in case of parameter substitution. gdb/testsuite/ChangeLog: 2021-11-16 Christina Schimpe <christina.schimpe@intel.com> * gdb.cp/templates.cc: New template class Cfoo with const, template, typdef and integer attributes. * gdb.cp/templates.exp: Add new test using ptype and ptype/r commmands for template class CFoo.
2021-11-05gdb/testsuite: use gdb_get_line_numberAndrew Burgess2-18/+4
Replaces a hard coded line number with a use of gdb_get_line_number. I suspect that the line number has, over time, come adrift from where it was supposed to be stopping. When the test was first added, line 770 pointed at the final 'return 0' in function main. Over time, as things have been added, line 770 now points at some random location in the middle of main. So, I've marked the 'return 0' with a comment, and now the test will always stop there. I also removed an old comment from 1997 talking about how these tests will only pass with the HP compiler, followed by an additional comment from 2000 saying that the tests now pass with GCC. I get the same results before and after this change.
2021-10-28[gdb/testsuite] Initialize anonymous union in gdb.cp/koenig.ccKavitha Natarajan1-0/+2
GDB test fails while running the test case gdb.cp/koenig.exp using clang compiler: [...] p foo (p_union) No symbol "p_union" in current context. (gdb) FAIL: gdb.cp/koenig.exp: p foo (p_union) [...] In the testcase, "p_union" is an unused/uninitialized variable of anonymous union type. Clang does not emit symbol for unused anonymous union/struct variables at any optimization level. Since the compiler itself is not emitting the symbol for "p_union", debug info is also not emitted when built with debug option. If the anonymous union is initialized (or used), then clang emits the symbol "p_union" which enables emitting debug info for "p_union". [...] p foo (p_union) Cannot resolve function foo to any overloaded instance (gdb) PASS: gdb.cp/koenig.exp: p foo (p_union) [...]
2021-10-21Fix test step-and-next-inline.ccCarl Love2-2/+4
The test expect the runto_main to stop at the first line of the function. Depending on the optimization level, gdb may stop in the prolog or after the prolog at the first line. To ensure the test stops at the first line of main, have it explicitly stop at a break point on the first line of the function. On PowerPC, the test passes when compiled with no optimization but fails with all levels of optimization due to gdb stopping in the prolog.
2021-09-30gdb/testsuite: make runto_main not pass no-message to runtoSimon Marchi24-26/+0
As follow-up to this discussion: https://sourceware.org/pipermail/gdb-patches/2020-August/171385.html ... make runto_main not pass no-message to runto. This means that if we fail to run to main, for some reason, we'll emit a FAIL. This is the behavior we want the majority of (if not all) the time. Without this, we rely on tests logging a failure if runto_main fails, otherwise. They do so in a very inconsisteny mannet, sometimes using "fail", "unsupported" or "untested". The messages also vary widly. This patch removes all these messages as well. Also, remove a few "fail" where we call runto (and not runto_main). by default (without an explicit no-message argument), runto prints a failure already. In two places, gdb.multi/multi-re-run.exp and gdb.python/py-pp-registration.exp, remove "message" passed to runto. This removes a few PASSes that we don't care about (but FAILs will still be printed if we fail to run to where we want to). This aligns their behavior with the rest of the testsuite. Change-Id: Ib763c98c5f4fb6898886b635210d7c34bd4b9023
2021-09-25[gdb/testsuite] Minimize gdb restartsTom de Vries4-7/+1
Minimize gdb restarts, applying the following rules: - don't use prepare_for_testing unless necessary - don't use clean_restart unless necessary Also, if possible, replace build_for_executable + clean_restart with prepare_for_testing for brevity. Touches 68 test-cases. Tested on x86_64-linux.
2021-08-03[gdb/testsuite] templates.exp to accept clang++ outputAlok Kumar Sharma1-0/+3
Please consider below testcase with intended error. `````````` constexpr const char cstring[] = "Eta"; template <const char*, typename T> class Column {}; using quick = Column<cstring,double>; // cstring without '&' void lookup() { quick c1; c1.ls(); } `````````` It produces below error. `````````` no member named 'ls' in 'Column<&cstring, double>'. `````````` Please note that error message contains '&' for cstring, which is absent in actual program. Clang++ does not generate & in such cases and this should also be accepted as correct output. gdb/testsuite/ChangeLog: * gdb.cp/templates.exp: Accept different but correct output from the Clang++ compiled binary also.
2021-07-21[gdb/testsuite] Fix gdb.cp/step-and-next-inline.exp with gcc-11Tom de Vries3-13/+84
When running test-case gdb.cp/step-and-next-inline.exp with gcc-11, I run into: ... KPASS: gdb.cp/step-and-next-inline.exp: no_header: next step 1 \ (PRMS symtab/25507) FAIL: gdb.cp/step-and-next-inline.exp: no_header: next step 2 KPASS: gdb.cp/step-and-next-inline.exp: no_header: next step 3 \ (PRMS symtab/25507) ... [ Note that I get the same result with gcc-11 and target board unix/gdb:debug_flags=-gdwarf-4, so this is not a dwarf 4 vs 5 issue. ] With gcc-10, I have this trace: ... 64 get_alias_set (&xx); get_alias_set (t=0x601038 <xx>) at step-and-next-inline.cc:51 51 if (t != NULL 40 if (t->x != i) 52 && TREE_TYPE (t).z != 1 43 return x; 53 && TREE_TYPE (t).z != 2 43 return x; 54 && TREE_TYPE (t).z != 3) 43 return x; main () at step-and-next-inline.cc:65 65 return 0; ... and with gcc-11, I have instead: ... 64 get_alias_set (&xx); get_alias_set (t=0x601038 <xx>) at step-and-next-inline.cc:51 51 if (t != NULL 52 && TREE_TYPE (t).z != 1 43 return x; 53 && TREE_TYPE (t).z != 2 43 return x; 54 && TREE_TYPE (t).z != 3) 43 return x; main () at step-and-next-inline.cc:65 65 return 0; ... and with clang-10, I have instead: ... 64 get_alias_set (&xx); get_alias_set (t=0x601034 <xx>) at step-and-next-inline.cc:51 51 if (t != NULL 52 && TREE_TYPE (t).z != 1 53 && TREE_TYPE (t).z != 2 54 && TREE_TYPE (t).z != 3) 51 if (t != NULL 57 } main () at step-and-next-inline.cc:65 65 return 0; ... The test-case tries to verify that we don't step into inlined function tree_check (lines 40-43) (so, with the clang trace we get that right). The test-case then tries to kfail the problems when using gcc, but this is done in such a way that the testing still gets out of sync after a failure. That is: the "next step 2" check that is supposed to match "TREE_TYPE (t).z != 2" is actually matching "TREE_TYPE (t).z != 1": ... (gdb) next^M 52 && TREE_TYPE (t).z != 1^M (gdb) PASS: gdb.cp/step-and-next-inline.exp: no_header: next step 2 ... Fix this by issuing extra nexts to arrive at the required lines. Tested on x86_64-linux, with gcc-8, gcc-9, gcc-10, gcc-11, clang-8, clang-10 and clang-12. gdb/testsuite/ChangeLog: 2021-07-20 Tom de Vries <tdevries@suse.de> * gdb.cp/step-and-next-inline.cc (tree_check, get_alias_set, main): Tag closing brace with comment. * gdb.cp/step-and-next-inline.h: Update to keep identical with step-and-next-inline.cc. * gdb.cp/step-and-next-inline.exp: Issue extra next when required.
2021-07-21[gdb/testsuite] Fix FAILs due to PR gcc/101452Tom de Vries4-4/+28
When running test-case gdb.base/ptype-offsets.exp with gcc-11 (with -gdwarf-5 default) or gcc-10 with target board unix/gdb:debug_flags=-gdwarf-5 we run into this regression: ... (gdb) ptype/o static_member^M /* offset | size */ type = struct static_member {^M - static static_member Empty;^M /* 0 | 4 */ int abc;^M ^M /* total size (bytes): 4 */^M }^M -(gdb) PASS: gdb.base/ptype-offsets.exp: ptype/o static_member +(gdb) FAIL: gdb.base/ptype-offsets.exp: ptype/o static_member ... This is caused by missing debug info, which I filed as gcc PR101452 - "[debug, dwarf-5] undefined static member removed by -feliminate-unused-debug-symbols". It's not clear yet whether this is a bug or a feature, but work around this in the test-cases by: - defining the static member - adding additional_flags=-fno-eliminate-unused-debug-types. Tested on x86_64-linux. gdb/testsuite/ChangeLog: 2021-07-20 Tom de Vries <tdevries@suse.de> * lib/gdb.exp (gcc_major_version): New proc. * gdb.base/ptype-offsets.cc: Define static member static_member::Empty. * gdb.cp/templates.exp: Define static member using -DGCC_BUG. * gdb.cp/m-static.exp: Add additional_flags=-fno-eliminate-unused-debug-types. * gdb.cp/pr-574.exp: Same. * gdb.cp/pr9167.exp: Same.
2021-07-13gdb, dwarf: Don't follow the parent of a subprogram to get a prefix.Felix Willgerodt2-0/+93
During prefix resolution, if the parent is a subprogram, there is no need to go to the parent of the subprogram. The DIE will be local. For a program like: ~~~ class F1 { public: int a; int vvv () { class F2 { int f; }; F2 abcd; return 1; } }; ~~~ The class F2 should not be seen as a member of F1. Before: ~~~ (gdb) ptype abcd type = class F1::F2 { private: int f; } ~~~ After: ~~~ (gdb) ptype abcd type = class F2 { private: int f; } ~~~ gdb/ChangeLog: 2021-06-23 Felix Willgerodt <felix.willgerodt@intel.com> * dwarf2/read.c (determine_prefix): Return an empty prefix if the parent is a subprogram. gdb/testsuite/ChangeLog: 2021-06-23 Felix Willgerodt <felix.willgerodt@intel.com> * gdb.cp/nested-class-func-class.cc: New file. * gdb.cp/nested-class-func-class.exp: New file.
2021-06-25gdb: fix invalid arg coercion when calling static member functionsAndrew Burgess2-0/+12
In this commit: commit 7022349d5c86bae74b49225515f42d2e221bd368 Date: Mon Sep 4 20:21:13 2017 +0100 Stop assuming no-debug-info functions return int A new if case was added to call_function_by_hand_dummy to decide if a function should be considered prototyped or not. Previously the code was structured like this: if (COND_1) ACTION_1 else if (COND_2) ACTION_2 else ACTION_3 With the new block the code now looks like this: if (COND_1) ACTION_1 if (NEW_COND) NEW_ACTION else if (COND_2) ACTION_2 else ACTION_3 Notice the new block was added as and 'if' not 'else if'. I'm running into a case where GDB executes ACTION_1 and then ACTION_2. Prior to the above commit GDB would only have executed ACTION_1. The actions in the code in question are trying to figure out if a function should be considered prototyped or not. When a function is not prototyped some arguments will be coerced, e.g. floats to doubles. The COND_1 / ACTION_1 are a very broad, any member function should be considered prototyped, however, after the above patch GDB is now executing the later ACTION_2 which checks to see if the function's type has the 'prototyped' flag set - this is not the case for the member functions I'm testing, and so GDB treats the function as unprototyped and casts the float argument to a double. I believe that adding the new check as 'if' rather than 'else if' was a mistake, and so in this commit I add in the missing 'else'. gdb/ChangeLog: * infcall.c (call_function_by_hand_dummy): Add missing 'else' when setting prototyped flag. gdb/testsuite/ChangeLog: * gdb.cp/method-call-in-c.cc (struct foo_type): Add static member function static_method. (global_var): New global. (main): Use new static_method to ensure it is compiled in. * gdb.cp/method-call-in-c.exp: Test calls to static member function.
2021-06-25gdb: replace NULL terminated array with array_viewAndrew Burgess2-1/+13
After the previous commit, this commit updates the value_struct_elt function to take an array_view rather than a NULL terminated array of values. The requirement for a NULL terminated array of values actually stems from typecmp, so the change from an array to array_view needs to be propagated through to this function. While making this change I noticed that this fixes another bug, in value_x_binop and value_x_unop GDB creates an array of values which doesn't have a NULL at the end. An array_view of this array is passed to value_user_defined_op, which then unpacks the array_view and passed the raw array to value_struct_elt, but only if the language is not C++. As value_x_binop and value_x_unop can only request member functions with the names of C++ operators, then most of the time, assuming the inferior is not a C++ program, then GDB will not find a matching member function with the call to value_struct_elt, and so typecmp will never be called, and so, GDB will avoid undefined behaviour. However, it is worth remembering that, when GDB's language is set to "auto", the current language is selected based on the language of the current compilation unit. As C++ programs usually link against libc, which is written in C, then, if the inferior is stopped in libc GDB will set the language to C. And so, it is possible that we will end up using value_struct_elt to try and lookup, and match, a C++ operator. If this occurs then GDB will experience undefined behaviour. I have extended the test added in the previous commit to also cover this case. Finally, this commit changes the API from passing around a pointer to an array to passing around a pointer to an array_view. The reason for this is that we need to be able to distinguish between the cases where we call value_struct_elt with no arguments, i.e. we are looking up a struct member, but we either don't have the arguments we want to pass yet, or we don't expect there to be any need for GDB to use the argument types to resolve any overloading; and the second case where we call value_struct_elt looking for a function that takes no arguments, that is, the argument list is empty. NOTE: While writing this I realise that if we pass an array_view at all then it will always have at least one item in it, the `this' pointer for the object we are planning to call the method on. So we could, I guess, pass an empty array_view to indicate the case where we don't know anything about the arguments, and when the array_view is length 1 or more, it means we do have the arguments. However, though we could do this, I don't think this would be better, the length 0 vs length 1 difference seems a little too subtle, I think that there's a better solution... I think a better solution would be to wrap the array_view in a gdb::optional, this would make the whole, do we have an array view or not question explicit. I haven't done this as part of this commit as making that change is much more extensive, every user of value_struct_elt will need to be updated, and as this commit already contains a bug fix, I wanted to keep the large refactoring in a separate commit, so, check out the next commit for the use of gdb::optional. gdb/ChangeLog: PR gdb/27994 * eval.c (structop_base_operation::evaluate_funcall): Pass array_view instead of array to value_struct_elt. * valarith.c (value_user_defined_op): Likewise. * valops.c (typecmp): Change parameter type from array pointer to array_view. Update header comment, and update body accordingly. (search_struct_method): Likewise. (value_struct_elt): Likewise. * value.h (value_struct_elt): Update declaration. gdb/testsuite/ChangeLog: PR gdb/27994 * gdb.cp/method-call-in-c.cc (struct foo_type): Add operator+=, change initial value of var member variable. (main): Make use of foo_type's operator+=. * gdb.cp/method-call-in-c.exp: Test use of operator+=.
2021-06-25gdb: fix regression in evaluate_funcall for non C++ like casesAndrew Burgess2-0/+87
This regression, as it is exposed by the test added in this commit, first became noticable with this commit: commit d182f2797922a305fbd1ef6a483cc39a56b43e02 Date: Mon Mar 8 07:27:57 2021 -0700 Convert c-exp.y to use operations But, this commit only added converted the C expression parser to make use of code that was added in this commit: commit a00b7254fb614af557de7ae7cc0eb39a0ce0e408 Date: Mon Mar 8 07:27:57 2021 -0700 Implement function call operations And it was this second commit that actually introduced the bugs (there are two). In structop_base_operation::evaluate_funcall we build up an argument list in the vector vals. Later in this function the argument list might be passed to value_struct_elt. Prior to commit a00b7254fb614 the vals vector (or argvec as it used to be called) stored the value for the function callee in the argvec at index 0. This 'callee' value is what ends up being passed to evaluate_subexp_do_call, and represents the function to be called, the value contents are the address of the function, and the value type is the function signature. The remaining items held in the argvec were the values to pass to the function. For a non-static member function the `this' pointer would be at index 1 in the array. After commit a00b7254fb614 this callee value is now held in a separate variable, not the vals array. So, for non-static member functions, the `this' pointer is now at index 0, with any other arguments after that. What this means is that previous, when we called value_struct_elt we would pass the address of argvec[1] as this was the first argument. But now we should be passing the address of vals[0]. Unfortunately, we are still passing vals[1], effectively skipping the first argument. The second issue is that, prior to commit a00b7254fb614, the argvec array was NULL terminated. This is required as value_struct_elt calls search_struct_method, which calls typecmp, and typecmp requires that the array have a NULL at the end. After commit a00b7254fb614 this NULL has been lost, and we are therefore violating the API requirements of typecmp. This commit fixes both of these regressions. I also extended the header comments on search_struct_method and value_struct_elt to make it clearer that the array required a NULL marker at the end. You will notice in the test attached to this commit that I test calling a non-static member function, but not calling a static member function. The reason for this is that calling static member functions is currently broken due to a different bug. That will be fixed in a later patch in this series, at which time I'll add a test for calling a static member function. gdb/ChangeLog: PR gdb/27994 * eval.c (structop_base_operation::evaluate_funcall): Add a nullptr to the end of the args array, which should not be included in the argument array_view. Pass all the arguments through to value_struct_elt. * valops.c (search_struct_method): Update header comment. (value_struct_elt): Likewise. gdb/testsuite/ChangeLog: PR gdb/27994 * gdb.cp/method-call-in-c.cc: New file. * gdb.cp/method-call-in-c.exp: New file.
2021-06-23[gdb/testsuite] Rewrite gdb_test_linesTom de Vries1-1/+1
On Ubuntu 20.04, when the debug info package for libc is not installed, I get: FAIL: gdb.base/info-types-c++.exp: info types FAIL: gdb.base/info-types-c.exp: info types The reason is that the output of info types is exactly: (gdb) info types All defined types: File /home/smarchi/src/binutils-gdb/gdb/testsuite/gdb.base/info-types.c: 52: typedef enum {...} anon_enum_t; 45: typedef struct {...} anon_struct_t; 68: typedef union {...} anon_union_t; 28: typedef struct baz_t baz; 31: typedef struct baz_t * baz_ptr; 21: struct baz_t; double 33: enum enum_t; float int 38: typedef enum enum_t my_enum_t; 17: typedef float my_float_t; 16: typedef int my_int_t; 54: typedef enum {...} nested_anon_enum_t; 47: typedef struct {...} nested_anon_struct_t; 70: typedef union {...} nested_anon_union_t; 30: typedef struct baz_t nested_baz; 29: typedef struct baz_t nested_baz_t; 39: typedef enum enum_t nested_enum_t; 19: typedef float nested_float_t; 18: typedef int nested_int_t; 62: typedef union union_t nested_union_t; 56: union union_t; unsigned int (gdb) The lines we expect in the test contain an empty line at the end: ... "62:\[\t \]+typedef union union_t nested_union_t;" \ "56:\[\t \]+union union_t;" \ "--optional" "\[\t \]+unsigned int" \ ""] This is written with the supposition that other files will be listed, so an empty line will be included to separate the symbols from this file from the next one. This empty line is not included when info-types.c is the only file listed. Fix this by rewriting gdb_test_lines to accept a single, plain tcl multiline regexp, such that we can write: ... "62:\[\t \]+typedef union union_t nested_union_t;" \ "56:\[\t \]+union union_t;(" \ "\[\t \]+unsigned int)?" \ "($|\r\n.*)"] ... Tested affected test-cases: - gdb.base/info-types-c.exp - gdb.base/info-types-c++.exp - gdb.base/info-macros.exp - gdb.cp/cplusfuncs.exp on x86_64-linux (openSUSE Leap 15.2), both with check and check-read1. Also tested the first two with gcc-4.8. Also tested on ubuntu 18.04. gdb/testsuite/ChangeLog: 2021-06-23 Tom de Vries <tdevries@suse.de> * lib/gdb.exp (gdb_test_lines): Rewrite to accept single multiline tcl regexp. * gdb.base/info-types.exp.tcl: Update. Make empty line at end of regexp optional. * gdb.base/info-macros.exp: Update. * gdb.cp/cplusfuncs.exp: Update.
2021-06-10[gdb/testsuite] Fix gdb.cp/nested-types.exp with check-read1Tom de Vries1-9/+2
With check-read1 I occasionally run into: ... FAIL: gdb.cp/nested-types.exp: ptype S10 (limit = 7) \ // parse failed (timeout) ... I can trigger this reliably by running check-read1 in conjunction with stress -c 5. Fix this by breaking up the regexp in cp_test_ptype_class. Tested on x86_64-linux. gdb/testsuite/ChangeLog: 2021-06-10 Tom de Vries <tdevries@suse.de> * lib/cp-support.exp (cp_test_ptype_class): Break up regexp. * gdb.cp/nested-types.exp: Remove usage of read1 timeout factor.
2021-06-10[gdb/testsuite] Fix gdb.cp/cplusfuncs.exp with check-read1Tom de Vries1-4/+7
When running check-read1, we run into: ... FAIL: gdb.cp/cplusfuncs.exp: info function for "operator=(" (timeout) ... Fix this by using using gdb_test_lines in info_func_regexp. Tested on x86_64-linux. gdb/testsuite/ChangeLog: 2021-06-10 Tom de Vries <tdevries@suse.de> * gdb.cp/cplusfuncs.exp (info_func_regexp): Use gdb_test_lines.
2021-06-01[gdb/symtab] Ignore cold clonesTom de Vries2-0/+84
Consider the test-case contained in this patch, compiled for c using gcc-10: ... $ gcc-10 -x c src/gdb/testsuite/gdb.cp/cold-clone.cc -O2 -g -Wall -Wextra ... When setting a breakpoint on foo, we get one breakpoint location: ... $ gdb -q -batch a.out -ex "b foo" Breakpoint 1 at 0x400560: file cold-clone.cc, line 28. ... However, when we compile for c++ instead, we get two breakpoint locations: ... $ gdb -q -batch a.out -ex "b foo" -ex "info break" Breakpoint 1 at 0x400430: foo. (2 locations) Num Type Disp Enb Address What 1 breakpoint keep y <MULTIPLE> 1.1 y 0x0000000000400430 in foo() at cold-clone.cc:30 1.2 y 0x0000000000400560 in foo() at cold-clone.cc:28 ... The additional breakpoint location at 0x400430 corresponds to the cold clone: ... $ nm a.out | grep foo 0000000000400560 t _ZL3foov 0000000000400430 t _ZL3foov.cold ... which demangled looks like this: ... $ nm -C a.out | grep foo 0000000000400560 t foo() 0000000000400430 t foo() [clone .cold] ... [ Or, in the case of the cc1 mentioned in PR23710: ... $ nm cc1 | grep do_rpo_vn.*cold 000000000058659d t \ _ZL9do_rpo_vnP8functionP8edge_defP11bitmap_headbb.cold.138 $ nm -C cc1 | grep do_rpo_vn.*cold 000000000058659d t \ do_rpo_vn(function*, edge_def*, bitmap_head*, bool, bool) [clone .cold.138] ... ] The cold clone is a part of the function that is split off from the rest of the function because it's considered cold (not frequently executed). So while the symbol points to code that is part of a function, it doesn't point to a function entry, so the desirable behaviour for "break foo" is to ignore this symbol. When compiling for c, the symbol "foo.cold" is entered as minimal symbol with the search name "foo.cold", and the lookup using "foo" fails to find that symbol. But when compiling for c++, the symbol "foo.cold" is entered as minimal symbol with both the mangled and demangled name, and for the demangled name "foo() [clone .cold]" we get the search name "foo" (because cp_search_name_hash stops hashing at '('), and the lookup using "foo" succeeds. Fix this by recognizing the cold clone suffix and returning false for such a minimal symbol in msymbol_is_function. Tested on x86_64-linux. gdb/ChangeLog: 2021-06-01 Tom de Vries <tdevries@suse.de> PR symtab/26096 * minsyms.c (msymbol_is_cold_clone): New function. (msymbol_is_function): Use msymbol_is_cold_clone. gdb/testsuite/ChangeLog: 2021-06-01 Tom de Vries <tdevries@suse.de> PR symtab/26096 * gdb.cp/cold-clone.cc: New test. * gdb.cp/cold-clone.exp: New file.
2021-04-07gdb: allow casting to rvalue reference in more casesAndrew Burgess2-0/+28
It is not currently possible to cast some values to an rvaule reference. This happens when simple scalar values are cast to an rvalue reference of the same type, e.g.: int global_var; Then in GDB: (gdb) p static_cast<int&&> (global_var) Attempt to take address of value not located in memory. Which is clearly silly. The problem is that as part of the cast an intermediate value is created within GDB that becomes an lval_none rather than the original lval_memory. The casting logic basically goes like this: The call tree that leads to the error looks like this: value_cast value_cast value_ref value_addr error The first value_cast call is casting the value for 'global_var' to type 'int&&'. GDB spots that the target type is a reference, and so calls value_cast again, this time casting 'global_var' to type 'int'. We then call value_ref to convert the result of the second value_cast into a reference. Unfortunately, the second cast results in the value (for global_var) changing from an lval_memory to an lval_none. This is because int to int casting calls extract_unsigned_integer and then value_from_longest. In theory value_cast has a check at its head that should help in this case, the code is: if (value_type (arg2) == type) return arg2; However, this only works in some cases. In our case 'value_type (arg2)' will be an objfile owned type, while the type from the expression parser 'int&&' will be gdbarch owned. The pointers will not be equal, but the meaning of the type will be equal. I did consider making the int to int casting case smarter, but this obviously is only one example. We must also consider things like float to float, or pointer to pointer.... So, I instead decided to try and make the initial check smarter. Instead of a straight pointer comparison, I now propose that we use types_deeply_equal. If this is true then we are casting something back to its current type, in which case we can preserve the lval setting by using value_copy. gdb/ChangeLog: * valops.c (value_cast): Call value_deeply_equal before performing any cast. gdb/testsuite/ChangeLog: * gdb.cp/rvalue-ref-params.cc (f3): New function. (f4): New function. (global_int): New global variable. (global_float): Likeiwse. (main): Call both new functions. * gdb.cp/rvalue-ref-params.exp: Add new tests.
2021-03-26gdb/testsuite: resolve remaining duplicate test names in gdb.cp/*.expAndrew Burgess11-21/+32
This commit resolves the remaining duplicate test names in gdb.cp/*.exp. These are all the easy duplicates, I'm either giving tests a new, unique name, extending an existing name to make it unique, or changing an existing name to better reflect what the test is actually doing, and thus, making this test name unique. There should be no change in what is tested after this commit. gdb/testsuite/ChangeLog: * gdb.cp/breakpoint.exp: Extend test names to make them unique. * gdb.cp/casts.exp: Give tests unique names. * gdb.cp/filename.exp: Likewise. * gdb.cp/gdb2495.exp: Likewise. * gdb.cp/mb-ctor.exp: Extend test names to make them unique. * gdb.cp/misc.exp: Rename test to make it unique. * gdb.cp/nsnested.exp: Give tests unique names. * gdb.cp/ovldbreak.exp: Likewise. * gdb.cp/pr17494.exp: Rename test to reflect what is actually being tested. This also removes the duplicate test name. * gdb.cp/ref-types.exp: Likewise. * gdb.cp/temargs.exp: Likewise.
2021-03-26gdb/testsuite: resolve duplicate test name in gdb.cp/cplusfuncs.expAndrew Burgess1-1/+1
While resolving duplicate test names I spotted that a test in gdb.cp/cplusfuncs.exp included an unescaped '[]'. In TCL square brackets enclose expressions to evaluate, and so in this case, where there is no enclosed expression, this just evaluates to the empty string. This clearly was not what the test intended, so in this commit I have escaped the square brackets. This has extended the test coverage. gdb/testsuite/ChangeLog: * gdb.cp/cplusfuncs.exp (test_paddr_operator_functions): Escape square brackets in test.
2021-03-26gdb/testsuite: remove duplicate test from gdb.cp/maint.expAndrew Burgess1-15/+16
I wanted to remove the duplicate test name from gdb.cp/maint.exp. In this test we run some checks against different operator names. For one operator we test with a variable number of spaces. However, we were accidentally testing the one space version twice, and the zero space version not at all, leading to a duplicate test name. I could have just changed the duplicate one space version into the missing zero space version, but I thought it would be neater to wrap multiple tests in a loop, and check all operators with either zero, one, or two spaces. These tests are super quick so take almost no extra time, and this gives marginally more test coverage. gdb/testsuite/ChangeLog: * gdb.cp/maint.exp (test_first_component): Run more tests with a variable number of spaces, this removes the duplicate testing of 'operator ->' which existed before.
2021-03-26gdb/testsuite: remove duplicate test names from gdb.cp/gdb2384.expAndrew Burgess2-12/+12
The test gdb.cp/gdb2384.exp contains some duplicate test names, and also some test names with a string inside parentheses at the end. In order to resolve the duplicates the obvious choice would be to add yet more strings inside parentheses at the end of names, however, this is discouraged in our test naming scheme. The string in parentheses originates from a comment in the test source code, which naturally leads to including this comment in the test name. In this commit I have changed the comment in the test source to remove the string in parentheses, I then rename the tests in the .exp script to match, making sure that all test names are unique. There should be no change in test coverage after this commit. gdb/testsuite/ChangeLog: * gdb.cp/gdb2384.cc (main): Change comments used for breakpoints. * gdb.cp/gdb2384.exp: Change and extend test names to avoid duplicates, and also to avoid having a string inside parentheses at the end of test names.
2021-03-26gdb/testsuite: remove duplicate test names for gdb.cp/nsusing.expAndrew Burgess1-100/+33
In trying to resolve the duplicate test names for the gdb.cp/nsusing.exp script, I ended up giving the test script a serious spring clean. This reverts some of the changes introduced in commit df83a9bf8b0d, but I don't think that we have lost any testing. The test program is made of many functions, the test script wants to stop in different functions and check which symbols are in scope. Previously the test script would either restart GDB completely in order to "progress" to the next function, or the script would restart the test program using 'runto'. In this commit I have reordered the steps of the test to correspond to program order, I then progress through the test program once by just placing a breakpoint and then continuing. As I said, the test is checking which symbols are in scope at each location, so the exact order of the tests doesn't matter, so long as we check the correct symbols at each location. I have also given the comments capital letters and full stops, and re-wrapped them to a more sensible line length. There was a duplicate test block introduced in the df83a9bf8b0d commit which I have removed in this commit, this duplicate code was responsible for one of the duplicate test names. The other duplicate test name was due to the same command being run at different locations, in this case I just gave the two tests explicit, unique, names. gdb/testsuite/ChangeLog: * gdb.cp/nsusing.exp: Rewrite test, remove a duplicate test block. Avoid repeated uses of 'runto', and instread just progress once through the test stopping at different breakpoints. Give comments a capital letter and full stop. Give duplicate tests unique names.
2021-01-22gdb/testsuite: eliminate gdb_suppress_tests mechanismSimon Marchi1-7/+3
There is a lot of support code for the test suppression mechanism. But as far as I know, it is not useful. The gdb_suppress_tests proc is in fact disabled with this comment that has been there since forever: return; # fnf - disable pending review of results where # testsuite ran better without this I suggest to just remove everything related to test suppression, that removes some unnecessary complexity from the support code and the tests. gdb/testsuite/ChangeLog: * lib/gdb.exp (gdb_test_multiple): Remove things related to test suppression. (default_gdb_exit): Likewise. (default_gdb_spawn): Likewise. (send_gdb): Likewise. (gdb_expect): Likewise. (gdb_expect_list): Likewise. (default_gdb_init): Likewise. (gdb_suppress_entire_file): Remove. (gdb_suppress_tests): Remove. (gdb_stop_suppressing_tests): Remove. (gdb_clear_suppressed): Remove. * lib/mi-support.exp (mi_uncatched_gdb_exit): Remove things related to test suppression. (default_mi_gdb_start): Likewise. (mi_gdb_reinitialize_dir): Likewise. (mi_gdb_test): Likewise. (mi_run_cmd_full): Likewise. (mi_runto_helper): Likewise. (mi_execute_to): Likewise. * lib/prompt.exp (default_prompt_gdb_start): Likewise. * gdb.base/bitfields.exp: Likewise. * gdb.base/bitfields2.exp: Likewise. * gdb.base/break.exp: Likewise. * gdb.base/call-sc.exp: Likewise. * gdb.base/callfuncs.exp: Likewise. * gdb.base/dfp-test.exp: Likewise. * gdb.base/endian.exp: Likewise. * gdb.base/exprs.exp: Likewise. * gdb.base/funcargs.exp: Likewise. * gdb.base/hbreak2.exp: Likewise. * gdb.base/recurse.exp: Likewise. * gdb.base/scope.exp: Likewise. * gdb.base/sepdebug.exp: Likewise. * gdb.base/structs.exp: Likewise. * gdb.base/until.exp: Likewise. * gdb.cp/misc.exp: Likewise. Change-Id: Ie6d3025091691ba72010faa28b85ebd417b738f7
2021-01-01Update copyright year range in all GDB filesJoel Brobecker301-301/+301
This commits the result of running gdb/copyright.py as per our Start of New Year procedure... gdb/ChangeLog Update copyright year range in copyright header of all GDB files.
2020-12-31Fix passing debug options for gccBernd Edlinger1-1/+1
Fix a bug in the test where we were missing "additional_flags=", causing -gstatement-frontiers not to be passed to the compiler. The issue was introduced in eb24648c453c28f2898fb599311ba004394a8b41 ("Fix gdb.cp/step-and-next-inline.exp with Clang"). gdb/testsuite: 2020-12-31 Bernd Edlinger <bernd.edlinger@hotmail.de> * gdb.cp/step-and-next-inline.exp: Fix test case.
2020-11-10Fix gdb.cp/step-and-next-inline.exp with ClangGary Benson1-4/+16
Clang fails to compile gdb.cp/step-and-next-inline.cc, with the following error: clang-12: error: unknown argument: '-gstatement-frontiers' compiler exited with status 1 This commit fixes the testcase by only passing -gstatement-frontiers when building with GCC. This commit also alters two checks marked as known failures, to mark them as known failures only when built using GCC. gdb/testsuite/ChangeLog: * gdb.cp/step-and-next-inline.exp: Only require -gstatement-frontiers when building with GCC. Only setup KFAIL's for GCC issues when using a GCC-built executable.
2020-11-06gdb: fix debug expression dumping of function call expressionsAndrew Burgess1-18/+6
In commit: commit 6d81691950f8c4be4a49a85a672255c140e82468 CommitDate: Sat Sep 19 09:44:58 2020 +0100 gdb/fortran: Move Fortran expression handling into f-lang.c A bug was introduced that broke GDB's ability to perform debug dumps of expressions containing function calls. For example this would no longer work: (gdb) set debug expression 1 (gdb) print call_me (&val) Dump of expression @ 0x4eced60, before conversion to prefix form: Language c, 12 elements, 16 bytes each. Index Opcode Hex Value String Value 0 OP_VAR_VALUE 40 (............... 1 OP_M2_STRING 79862864 P............... 2 unknown opcode: 224 79862240 ................ 3 OP_VAR_VALUE 40 (............... 4 OP_VAR_VALUE 40 (............... 5 OP_RUST_ARRAY 79861600 `............... 6 UNOP_PREDECREMENT 79861312 @............... 7 OP_VAR_VALUE 40 (............... 8 UNOP_ADDR 61 =............... 9 OP_FUNCALL 46 ................ 10 BINOP_ADD 1 ................ 11 OP_FUNCALL 46 ................ Dump of expression @ 0x4eced60, after conversion to prefix form: Expression: `call_me (&main::val, VAL(Aborted (core dumped) The situation was even worse for Fortran function calls, or array indexes, which both make use of the same expression opcode. The problem was that in a couple of places the index into the expression array was handled incorrectly causing GDB to interpret elements incorrectly. These issues are fixed in this commit. There are already some tests to check GDB when 'set debug expression 1' is set, these can be found in gdb.*/debug-expr.exp. Unfortunately the cases above were not covered. In this commit I have cleaned up all of the debug-expr.exp files a little, there was a helper function that had clearly been copied into each file, this is now moved into lib/gdb.exp. I've added a gdb.fortran/debug-expr.exp test file, and extended gdb.base/debug-expr.exp to cover the function call case. gdb/ChangeLog: * expprint.c (print_subexp_funcall): Increment expression position after reading argument count. * f-lang.c (print_subexp_f): Skip over opcode before calling common function. (dump_subexp_body_f): Likewise. gdb/testsuite/ChangeLog: * gdb.base/debug-expr.c: Add extra function to allow for an additional test. * gdb.base/debug-expr.exp (test_debug_expr): Delete, replace calls to this proc with gdb_test_debug_expr. Add an extra test. * gdb.cp/debug-expr.exp (test_debug_expr): Delete, replace calls to this proc with gdb_test_debug_expr, give the tests names * gdb.dlang/debug-expr.exp (test_debug_expr): Delete, replace calls to this proc with gdb_test_debug_expr, give the tests names * gdb.fortran/debug-expr.exp: New file. * gdb.fortran/debug-expr.f90: New file. * lib/gdb.exp (gdb_test_debug_expr): New proc.
2020-10-28[gdb/testsuite] Fix gdb.cp/nsalias.exp with -readnowTom de Vries1-4/+16
When running test-case gdb.cp/nsalias.exp with target board readnow, we get: ... FAIL: gdb.cp/nsalias.exp: complaint for too many recursively imported \ declarations ... The complaint is not detected, because: - the complaint is triggered during the file command instead of during "print N100::x" - the "set complaints 1" is not effective because it's issued after the file command Fix the FAIL by setting the complaints limit earlier, and detecting the complaint also during the file command. Tested on x86_64-linux. gdb/testsuite/ChangeLog: 2020-10-28 Tom de Vries <tdevries@suse.de> * lib/gdb.exp (gdb_file_cmd): Set gdb_file_cmd_msg. * gdb.cp/nsalias.exp: Set complaints limit before file cmd. Expect complaint during file command for -readnow.
2020-10-28[gdb/testsuite] Fix typo in gdb.cp/nsalias.expTom de Vries1-1/+1
Fix typo "compaint" -> "complaint". gdb/testsuite/ChangeLog: 2020-10-28 Tom de Vries <tdevries@suse.de> * gdb.cp/nsalias.exp: Fix typo in test name.
2020-10-27[gdb/testsuite] Fix gdb.cp/psymtab-parameter.exp with -readnowTom de Vries1-3/+4
When running test-case gdb.cp/psymtab-parameter.exp with target board readnow, we run into: ... FAIL: gdb.cp/psymtab-parameter.exp: maintenance info symtabs ... The FAIL is expected, as mentioned in the comment: ... # The goal is to keep the CU (Compilation Unit) unexpanded. It would be # rather XFAIL than FAIL here. For example -readnow breaks it. gdb_test_no_output "maintenance info symtabs" ... Fix the FAIL by skipping the command for -readnow. Tested on x86_64-linux. gdb/testsuite/ChangeLog: 2020-10-27 Tom de Vries <tdevries@suse.de> * gdb.cp/psymtab-parameter.exp: Don't expect unexpanded CU for -readnow.
2020-10-13gdb/testsuite/: Use "-qualified" in explicit "break main", etc.Pedro Alves1-1/+1
Similar to the previous patch, but this time add "-q" to tests that do "break main", "list main", etc. explicitly. gdb/testsuite/ChangeLog: * config/monitor.exp: Use "list -q". * gdb.arch/gdb1558.exp: Use "break -q". * gdb.arch/i386-permbkpt.exp: Use "break -q". * gdb.arch/i386-prologue-skip-cf-protection.exp: Use "break -q". * gdb.base/break.exp: Use "break -q", "list -q" and "tbreak -q". * gdb.base/commands.exp: Use "break -q". * gdb.base/condbreak.exp: Use "break -q". * gdb.base/ctf-ptype.exp: Use "list -q". * gdb.base/define.exp: Use "break -q". * gdb.base/del.exp: Use "break -q". * gdb.base/fullname.exp: Use "break -q". * gdb.base/hbreak-in-shr-unsupported.exp: Use "hbreak -q". * gdb.base/hbreak-unmapped.exp: Use "hbreak -q". * gdb.base/hbreak2.exp: Use "hbreak -q" and "list -q". * gdb.base/hw-sw-break-same-address.exp: Use "break -q" and "hbreak -q". * gdb.base/included.exp: Use "list -q". * gdb.base/label.exp: Use "break -q". * gdb.base/lineinc.exp: Use "break -q". * gdb.base/list.exp: Use "list -q". * gdb.base/macscp.exp: Use "list -q". * gdb.base/pending.exp: Use "break -q". * gdb.base/prologue-include.exp: Use "break -q". * gdb.base/ptype.exp: Use "list -q". * gdb.base/sepdebug.exp: Use "break -q", "list -q" and "tbreak -q". * gdb.base/server-del-break.exp: Use "break -q". * gdb.base/style.exp: Use "break -q". * gdb.base/symbol-without-target_section.exp: Use "list -q". * gdb.base/watchpoint-reuse-slot.exp: Use "hbreak -q". * gdb.cp/exception.exp: Use "tbreak -q". * gdb.dwarf2/dw2-error.exp: Use "break -q". * gdb.dwarf2/fission-mix.exp: Use "break -q". * gdb.dwarf2/fission-reread.exp: Use "break -q". * gdb.dwarf2/pr13961.exp: Use "break -q". * gdb.linespec/explicit.exp: Use "list -q". * gdb.linespec/linespec.exp: Use "break -q". * gdb.mi/mi-simplerun.exp: Use "--qualified". * gdb.python/py-mi-objfile-gdb.py: Use "list -q". * gdb.server/bkpt-other-inferior.exp: Use "break -q". * gdb.server/connect-without-multi-process.exp: Use "break -q". * gdb.trace/change-loc.exp: Use "break -q". * gdb.trace/pending.exp: Use "break -q". * gdb.tui/basic.exp: Use "list -q". * gdb.tui/list-before.exp: Use "list -q". * gdb.tui/list.exp: Use "list -q". * lib/gdb.exp (gdb_has_argv0): Use "break -q". Change-Id: Iab9408e90ed71cbb111cd737d2d81b5ba8adb108
2020-10-12Reject ambiguous C++ field accesses (PR exp/26602)Pedro Alves2-156/+258
The gdb.cp/ambiguous.exp testcase had been disabled for many years, but recently it was re-enabled. However, it is failing everywhere. That is because it is testing an old feature that is gone from GDB. The testcase is expecting to see an ambiguous field warning, like: # X is derived from A1 and A2; both A1 and A2 have a member 'x' send_gdb "print x.x\n" gdb_expect { -re "warning: x ambiguous; using X::A2::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" { pass "print x.x" } -re "warning: x ambiguous; using X::A1::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" { pass "print x.x" } -re ".*$gdb_prompt $" { fail "print x.x" } timeout { fail "(timeout) print x.x" } } However, GDB just accesses one of the candidates without warning or error: print x.x $1 = 1431655296 (gdb) FAIL: gdb.cp/ambiguous.exp: print x.x (The weird number is because the testcase does not initialize the variables.) The testcase come in originally with the big HP merge: +Sun Jan 10 23:44:11 1999 David Taylor <taylor@texas.cygnus.com> + + + The following files are part of the HP merge; some had longer + names at HP, but have been renamed to be no more than 14 + characters in length. Looking at the tree back then, we find that warning: /* Helper function used by value_struct_elt to recurse through baseclasses. Look for a field NAME in ARG1. Adjust the address of ARG1 by OFFSET bytes, and search in it assuming it has (class) type TYPE. If found, return value, else return NULL. If LOOKING_FOR_BASECLASS, then instead of looking for struct fields, look for a baseclass named NAME. */ static value_ptr search_struct_field (name, arg1, offset, type, looking_for_baseclass) char *name; register value_ptr arg1; int offset; register struct type *type; int looking_for_baseclass; { int found = 0; char found_class[1024]; value_ptr v; struct type *vbase = NULL; found_class[0] = '\000'; v = search_struct_field_aux (name, arg1, offset, type, looking_for_baseclass, &found, found_class, &vbase); if (found > 1) warning ("%s ambiguous; using %s::%s. Use a cast to disambiguate.", name, found_class, name); return v; } However, in current GDB, search_struct_field does not handle the ambiguous field case, nor is that warning found anywhere. Somehow it got lost over the years. That seems like a regression, because the compiler (as per language rules) rejects the ambiguous accesses as well. E.g.: gdb.cp/ambiguous.cc:98:5: error: request for member 'x' is ambiguous 98 | x.x = 1; | ^ gdb.cp/ambiguous.cc:10:7: note: candidates are: 'int A2::x' 10 | int x; | ^ gdb.cp/ambiguous.cc:4:7: note: 'int A1::x' 4 | int x; | ^ This patch restores the feature, though implemented differently and with better user experience, IMHO. An ambiguous access is now an error instead of a warning, and also GDB shows you all the candidates, like: (gdb) print x.x Request for member 'x' is ambiguous in type 'X'. Candidates are: 'int A1::x' (X -> A1) 'int A2::x' (X -> A2) (gdb) print j.x Request for member 'x' is ambiguous in type 'J'. Candidates are: 'int A1::x' (J -> K -> A1) 'int A1::x' (J -> L -> A1) Users can then fix their commands by casting or by specifying the baseclass explicitly, like: (gdb) p x.A1::x $1 = 1 (gdb) p x.A2::x $2 = 2 (gdb) p ((A1) x).x $3 = 1 (gdb) p ((A2) x).x $4 = 2 (gdb) p j.K::x $12 = 1 (gdb) p j.L::x $13 = 2 (gdb) p j.A1::x base class 'A1' is ambiguous in type 'J' The last error I've not touched; could be improved to also list the baseclass candidates. The showing the class "path" for each candidate was inspired by GCC's output when you try an ambiguous cast: gdb.cp/ambiguous.cc:161:8: error: ambiguous conversion from derived class 'const JVA1' to base class 'const A1': class JVA1 -> class KV -> class A1 class JVA1 -> class A1 (A1) jva1; ^~~~ I did not include the "class" word as it seemed unnecessarily repetitive, but I can include it if people prefer it: (gdb) print j.x Request for member 'x' is ambiguous in type 'J'. Candidates are: 'int A1::x' (class J -> class K -> class A1) 'int A1::x' (class J -> class L -> class A1) The testcase is adjusted accordingly. I also took the chance to modernize it at the same time. Also, as mentioned above, the testcase doesn't currently initialize the tested variables. This patch inializes them all, giving each field a distinct value, so that we can be sure that GDB is accessing the right fields / offsets. The testcase is extended accordingly. Unfortunately, this exposes a bug, not addressed in this patch. The bug is around a class that inherits from A1 directly and also inherits from two other distinct base classes that inherit virtually from A1 in turn: print jva1.KV::x $51 = 1431665544 (gdb) FAIL: gdb.cp/ambiguous.exp: all fields: print jva1.KV::x print jva1.KV::y $52 = 21845 (gdb) FAIL: gdb.cp/ambiguous.exp: all fields: print jva1.KV::y (gdb) print /x (KV)jva1 $4 = {<A1> = <invalid address>, _vptr.KV = 0x555555557b88 <vtable for JVA1+24>, i = 0x457} (gdb) print /x (A1)(KV)jva1 Cannot access memory at address 0x0 Since that's an orthogonal issue, I filed PR c++/26550 and kfailed the tests that fail because of it. gdb/ChangeLog: PR exp/26602 * valops.c (struct struct_field_searcher): New. (update_search_result): Rename to ... (struct_field_searcher::update_result): ... this. Simplify prototype. Record all found fields. (do_search_struct_field): Rename to ... (struct_field_searcher::search): ... this. Simplify prototype. Maintain stack of visited baseclass path. Call update_result for fields too. Keep searching fields in baseclasses instead of stopping at the first found field. (search_struct_field): Use struct_field_searcher. When looking for fields, report ambiguous access attempts. gdb/testsuite/ChangeLog: PR exp/26602 PR c++/26550 * gdb.cp/ambiguous.cc (marker1): Delete. (main): Initialize all the fields of the locals. Replace marker1 call with a "set breakpoint here" marker. * gdb.cp/ambiguous.exp: Modernize. Use gdb_continue_to_breakpoint instead of running to marker1. Add tests printing all the variables and all the fields of the variables. (test_ambiguous): New proc, expecting the new GDB output when a field access is ambiguous. Change all "warning: X ambiguous" tests to use it.
2020-09-18gdb.cp/call-c.exp C++ifyPedro Alves1-0/+3
Make the testcase work when built with a C++ compiler. gdb/testsuite/ChangeLog: * gdb.cp/call-c-1.c (foo) [__cplusplus]: Add extern "C".
2020-09-13gdb/testsuite: Explicitly return from mainPedro Alves22-6/+39
I've been playing with a board file that forces every testcase to include a header file that does something like: #define main __gdb_testcase_main and then links an actual main() function that does some initialization and then jumps to __gdb_testcase_main. That runs into a number of testcases relying on main not having an explicit return statement, like e.g.,: gdb/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/catch-follow-exec.c:27:1: warning: non-void function does not return a value [-Wreturn-type] gdb/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/catch-signal.c:47:1: warning: non-void function does not return a value [-Wreturn-type] We don't get those warnings without my board because it is valid to not explicitly return from main. There's an implicit "return 0;". Since it doesn't hurt to be explicit, I've went ahead and added the explicit return statements. Also, a couple testcases either don't explicitly specify main's return type, or return void. Those are tweaked to explicitly return int. gdb/testsuite/ChangeLog: * gdb.base/catch-follow-exec.c (main): Add explicit return statement. * gdb.base/catch-signal.c (main): Likewise. * gdb.base/condbreak-call-false.c (main): Likewise. * gdb.base/consecutive.c (main): Add explicit return statement and return type. * gdb.base/cursal.c (main): Add explicit return statement. * gdb.base/cvexpr.c (main): Likewise. * gdb.base/display.c (main): Add explicit return statement and return type. * gdb.base/dprintf-detach.c (main): Add explicit return statement. * gdb.base/endianity.c (main): Likewise. * gdb.base/execd-prog.c (main): Likewise. * gdb.base/gdb1090.c (main): Likewise. * gdb.base/info_qt.c (main): Likewise. * gdb.base/lineinc.c (main): Likewise. * gdb.base/load-command.c (main): Likewise. * gdb.base/macscp1.c (main): Likewise. * gdb.base/pr10179-a.c (main): Likewise. * gdb.base/quit-live.c (main): Likewise. * gdb.base/scope0.c (main): Likewise. * gdb.base/settings.c (main): Likewise. * gdb.base/stack-checking.c (main): Return int. * gdb.base/varargs.c (main): Add explicit return statement. * gdb.cp/ambiguous.cc (main): Likewise. * gdb.cp/anon-struct.cc (main): Likewise. * gdb.cp/anon-union.cc (main): Likewise. * gdb.cp/bool.cc (main): Likewise. * gdb.cp/bs15503.cc (main): Likewise. * gdb.cp/cplusfuncs.cc (main): Likewise. * gdb.cp/cttiadd.cc (main): Likewise. * gdb.cp/extern-c.cc (main): Likewise. * gdb.cp/filename.cc (main): Likewise. * gdb.cp/formatted-ref.cc (main): Likewise. * gdb.cp/mb-ctor.cc (main): Likewise. * gdb.cp/member-ptr.cc (main): Likewise. * gdb.cp/minsym-fallback-main.cc (main): Likewise. * gdb.cp/overload-const.cc (main): Likewise. * gdb.cp/paren-type.cc (main): Likewise. * gdb.cp/parse-lang.cc (main): Likewise. * gdb.cp/pr-1023.cc (main): Likewise. * gdb.cp/psmang1.cc (main): Likewise. * gdb.cp/readnow-language.cc (main): Likewise. * gdb.cp/ref-params.cc (main): Likewise. * gdb.cp/rvalue-ref-params.cc (main): Likewise. * gdb.cp/virtbase2.cc (main): Likewise. * gdb.dwarf2/dw2-abs-hi-pc.c (main): Likewise. * gdb.dwarf2/dw2-namespaceless-anonymous.c (main): Likewise. * gdb.dwarf2/dw4-toplevel-types.cc (main): Likewise. * gdb.mi/mi-console.c (main): Likewise. * gdb.mi/mi-read-memory.c (main): Likewise. * gdb.modula2/multidim.c (main): Likewise. * gdb.opt/inline-small-func.c (main): Likewise. * gdb.python/py-rbreak.c (main): Likewise. * gdb.stabs/exclfwd1.c (main): Likewise. * gdb.trace/qtro.c (main): Likewise.
2020-09-13Remove stale "register" bits from gdb.cp/misc.ccPedro Alves3-41/+2
gdb.cp/misc.cc seems to have been originally copied from gdb.cp/classes.cc. The testcases that use it, misc.exp and inherit.exp don't reference the "register" bits anywhere. Remove them, since they trigger warnings with newer GCCs, given "register" is being removed in C++17. gdb/testsuite/ChangeLog: * gdb.cp/inherit.exp: No longer pass -Wno-deprecated-register. * gdb.cp/misc.exp: No longer pass -Wno-deprecated-register. * gdb.cp/misc.cc (class small, small::method, marker_reg1) (register_class): Delete. (main): Don't call register_class.
2020-09-13Move "register" test out of classes.exp to a separate testcasePedro Alves4-72/+124
The gdb.cp/classes.exp testcase has one test that tries to exercise the case of calling a method on a variable that has been put in a register. See the declaration of small in classes.cc: /* Try to get the compiler to allocate a class in a register. */ class small { public: int x; int method (); }; and the comment in classes.exp: # This class is so small that an instance of it can fit in a register. # When gdb tries to call a method, it gets embarrassed about taking # the address of a register. # # TODO: I think that message should be a PASS, not an XFAIL. # gdb prints an informative message and declines to do something # impossible. # # The method call actually succeeds if the compiler allocates very # small classes in memory instead of registers. So this test does # not tell us anything interesting if the call succeeds. # # -- chastain 2003-12-31 And these comments: https://gcc.gnu.org/legacy-ml/gcc/2010-05/msg00116.html https://gcc.gnu.org/legacy-ml/gcc/2010-05/msg00117.html "register keyword has other uses, e.g. for -O0 code variables declared with register keyword can be put into registers, while variables declared without it always get stack slots." "I think it does, without optimization. There's some unique GDB tests that use this. It causes them to be live between statements in a machine register instead of always stored in stack slots." The "register" keyword seems to be ignored by the compiler nowadays even at -O0, though. With or without the register keyword, the variable is given a stack slot, at least on x86-64 with GCC 9. However, if we use the GCC extension to put the variable in a specific variable: https://gcc.gnu.org/onlinedocs/gcc-10.2.0/gcc/Local-Register-Variables.html#Local-Register-Variables diff --git c/gdb/testsuite/gdb.cp/classes.cc w/gdb/testsuite/gdb.cp/classes.cc index 5ea360e4d06..6dcf34689b8 100644 --- c/gdb/testsuite/gdb.cp/classes.cc +++ w/gdb/testsuite/gdb.cp/classes.cc @@ -629,7 +629,7 @@ register_class () /* We don't call any methods for v, so gcc version cygnus-2.3.3-930220 might put this variable in a register. This is a lose, though, because it means that GDB can't call any methods for that variable. */ - register small v; + register small v asm ("rax"); then it works, and we get an XFAIL: print v.method () Address requested for identifier "v" which is in register $rax (gdb) XFAIL: gdb.cp/classes.exp: calling method for small class (PRMS 2972) I think that what we should do here is move this test into its own file, use that GCC syntax to force it to a register, and do as the comment says -- issue a pass instead of an XFAIL. That's what this commit does. Note that we don't need -Wno-deprecated-register (nor -Wno-register) anymore in the new testcase, because GNU register-asm local variables don't trigger the warning, with either GCC or Clang. gdb/testsuite/ChangeLog: * gdb.cp/classes.exp: No longer pass -Wno-deprecated-register. (do_tests): Remove "calling method for small class" test. * gdb.cp/classes.cc (class small, small::method, marker_reg1) (register_class): Delete. (main): Don't call register_class. * gdb.cp/call-method-register.exp: New file, based on bits removed from classes.exp. * gdb.cp/call-method-register.cc: New file, based on bits removed from classes.cc.
2020-09-11[gdb/testsuite] Kfail gdb.cp/ambiguous.exp FAILs for PR26602Tom de Vries1-0/+7
Kfail these FAILs as caused by PR exp/26602: ... FAIL: gdb.cp/ambiguous.exp: print x.x FAIL: gdb.cp/ambiguous.exp: print n.x FAIL: gdb.cp/ambiguous.exp: print j.x FAIL: gdb.cp/ambiguous.exp: print jva1.x FAIL: gdb.cp/ambiguous.exp: print jva2.x FAIL: gdb.cp/ambiguous.exp: print (A1)j FAIL: gdb.cp/ambiguous.exp: print (A1)jva1 ... Tested on x86_64-linux. gdb/testsuite/ChangeLog: 2020-09-11 Tom de Vries <tdevries@suse.de> PR exp/26602 * gdb.cp/ambiguous.exp: Add KFAILs for PR26602.
2020-08-25Enable gdb.cp/ambiguous.exp with GCC and clangGary Benson1-2/+10
gdb.cp/ambiguous.exp failed to build using clang with the following error: gdb compile failed, /gdbtest/src/gdb/testsuite/gdb.cp/ambiguous.cc:70:36: warning: direct base 'A1' is inaccessible due to ambiguity: class JVA1 -> class KV -> class A1 class JVA1 -> class A1 [-Winaccessible-base] class JVA1 : public KV, public LV, public A1 { ^~~~~~~~~ This commit builds this testcase with -Wno-inaccessible-base when using clang, to avoid this failure. Furthermore, gdb.cp/ambiguous.exp has been disabled when using GCC since 1998. This commit enables this testcase, building with -Wno-inaccessible-base when using GCC >= 10.1, and -w otherwise. gdb/testsuite/ChangeLog: * gdb.cp/ambiguous.exp: Enable test when compiling with GCC. Add additional_flags=-Wno-inaccessible-base when compiling with GCC >= 10.1 or clang. Add additional_flags=-w when compiling with GCC < 10.
2020-07-28Demangle function names when disassemblingAndrew Burgess2-0/+98
Andrew Burgess pointed out a regression, which he described in PR symtab/26270: ================ After commit: commit bcfe6157ca288efed127c5efe21ad7924e0d98cf (refs/bisect/bad) Date: Fri Apr 24 15:35:01 2020 -0600 Use the linkage name if it exists The disassembler no longer demangles function names in its output. So we see things like this: (gdb) disassemble tree_insert Dump of assembler code for function _Z11tree_insertP4nodei: .... Instead of this: (gdb) disassemble tree_insert Dump of assembler code for function tree_insert(node*, int): .... This is because find_pc_partial_function now returns the linkage name rather than the demangled name. ================ This patch fixes the problem by introducing a new "overload" of find_pc_partial_function, which returns the general_symbol_info rather than simply the name. This lets the disassemble command choose which name to show. Regression tested on x86-64 Fedora 32. gdb/ChangeLog 2020-07-28 Tom Tromey <tromey@adacore.com> PR symtab/26270: * symtab.h (find_pc_partial_function_sym): Declare. * cli/cli-cmds.c (disassemble_command): Use find_pc_partial_function_sym. Check asm_demangle. * blockframe.c (cache_pc_function_sym): New global. (cache_pc_function_name): Remove. (clear_pc_function_cache): Update. (find_pc_partial_function_sym): New function, from find_pc_partial_function. (find_pc_partial_function): Rewrite using find_pc_partial_function_sym. gdb/testsuite/ChangeLog 2020-07-28 Andrew Burgess <andrew.burgess@embecosm.com> PR symtab/26270: * gdb.cp/disasm-func-name.cc: New file. * gdb.cp/disasm-func-name.exp: New file.
2020-07-20Skip tests requiring "alignof (void)" when compiling using clangGary Benson1-1/+12
As an extension, GCC allows void pointer arithmetic, with sizeof(void) and alignof(void) both 1. GDB supports this extension, but clang does not, and fails to compile the generated output of gdb.cp/align.exp with the following error: gdb compile failed, /gdbtest/build/gdb/testsuite/outputs/gdb.cp/align/align.cc:28:23: error: invalid application of 'alignof' to an incomplete type 'void' unsigned a_void = alignof (void); ^ ~~~~~~ 1 error generated. This commit adds preprocessor conditionals to the generated output, to omit the unsupported code when using clang, and supplies the expected value so the test can complete. gdb/testsuite/ChangeLog: * gdb.cp/align.exp: Fix "alignof (void)" tests when compiling with clang.
2020-06-26Fix -Wstring-compare testcase build failureGary Benson2-2/+7
Clang fails to compile the file gdb/testsuite/gdb.cp/try_catch.cc with the following error: warning: result of comparison against a string literal is unspecified (use strncmp instead) [-Wstring-compare] This commit fixes the error, replacing the pointer comparison with a call to strcmp. This commit also adds a final check: the test program is run to the final return statement, and the value of "test" is checked to ensure it is still "true" at that point. gdb/testsuite/ChangeLog: * gdb.cp/try_catch.cc: Include string.h. (main): Replace comparison against string literal with strcmp, avoiding build failure with -Wstring-compare. Add "marker test-complete". * gdb.cp/try_catch.exp: Run the test to the above marker, then verify that the value of "test" is still true.
2020-06-23Improve -Wunused-value testcase build failures fixGary Benson6-31/+31
This commit improves upon my previous -Wunused-value fix by replacing the various dummy variables with casts to void, as suggested by Pedro. gdb/testsuite/ChangeLog: * gdb.cp/namespace.cc: Improve -Wunused-value fix. * gdb.cp/nsimport.cc: Likewise. * gdb.cp/nsnested.cc: Likewise. * gdb.cp/nsnoimports.cc: Likewise. * gdb.cp/nsusing.cc: Likewise. * gdb.cp/smartp.cc: Likewise. * gdb.python/py-pp-integral.c: Likewise. * gdb.python/py-pp-re-notag.c: Likewise.
2020-06-23Avoid testcase build failures with -Wunused-valueGary Benson6-31/+31
A number of testcases fail to build with -Wunused-value enabled. This commit adds dummy values to avoid this. gdb/testsuite/ChangeLog: * gdb.cp/namespace.cc: Avoid build failure with -Wunused-value. * gdb.cp/nsimport.cc: Likewise. * gdb.cp/nsnested.cc: Likewise. * gdb.cp/nsnoimports.cc: Likewise. * gdb.cp/nsusing.cc: Likewise. * gdb.cp/smartp.cc: Likewise. * gdb.python/py-pp-integral.c: Likewise. * gdb.python/py-pp-re-notag.c: Likewise.
2020-06-03[gdb/symtab] Fix missing breakpoint location for inlined functionTom de Vries4-0/+114
Consider the test-case contained in this patch. With -readnow, we have two breakpoint locations: ... $ gdb -readnow -batch breakpoint-locs -ex "b N1::C1::baz" -ex "info break" Breakpoint 1 at 0x4004cb: N1::C1::baz. (2 locations) Num Type Disp Enb Address What 1 breakpoint keep y <MULTIPLE> 1.1 y 0x00000000004004cb in N1::C1::baz() \ at breakpoint-locs.h:6 1.2 y 0x00000000004004f0 in N1::C1::baz() \ at breakpoint-locs.h:6 ... But without -readnow, we have instead only one breakpoint location: ... $ gdb -batch breakpoint-locs -ex "b N1::C1::baz" -ex "info break" Breakpoint 1 at 0x4004f0: file breakpoint-locs.h, line 6. Num Type Disp Enb Address What 1 breakpoint keep y 0x00000000004004f0 in N1::C1::baz() \ at breakpoint-locs.h:6 ... The relevant dwarf is this bit: ... <0><d2>: Abbrev Number: 1 (DW_TAG_compile_unit) <d8> DW_AT_name : breakpoint-locs.cc <1><f4>: Abbrev Number: 2 (DW_TAG_namespace) <f5> DW_AT_name : N1 <2><fe>: Abbrev Number: 3 (DW_TAG_class_type) <ff> DW_AT_name : C1 <3><109>: Abbrev Number: 4 (DW_TAG_subprogram) <10a> DW_AT_name : baz <110> DW_AT_linkage_name: _ZN2N12C13bazEv <2><116>: Abbrev Number: 5 (DW_TAG_subprogram) <117> DW_AT_name : foo <11d> DW_AT_linkage_name: _ZN2N13fooEv <1><146>: Abbrev Number: 8 (DW_TAG_subprogram) <147> DW_AT_specification: <0x116> <14b> DW_AT_low_pc : 0x4004c7 <153> DW_AT_high_pc : 0x10 <2><161>: Abbrev Number: 9 (DW_TAG_inlined_subroutine) <162> DW_AT_abstract_origin: <0x194> <166> DW_AT_low_pc : 0x4004cb <16e> DW_AT_high_pc : 0x9 <1><194>: Abbrev Number: 12 (DW_TAG_subprogram) <195> DW_AT_specification: <0x109> <199> DW_AT_inline : 3 (declared as inline and inlined) ... The missing breakpoint location is specified by DIE 0x161, which is ignored by the partial DIE reader because it's a child of a DW_TAG_subprogram DIE (at 0x146, for foo). Fix this by not ignoring the DIE during partial DIE reading. Tested on x86_64-linux. gdb/ChangeLog: 2020-06-03 Tom de Vries <tdevries@suse.de> PR symtab/26046 * dwarf2/read.c (scan_partial_symbols): Recurse into DW_TAG_subprogram children for C++. (load_partial_dies): Don't skip DW_TAG_inlined_subroutine child of DW_TAG_subprogram. gdb/testsuite/ChangeLog: 2020-06-03 Tom de Vries <tdevries@suse.de> PR symtab/26046 * gdb.cp/breakpoint-locs-2.cc: New test. * gdb.cp/breakpoint-locs.cc: New test. * gdb.cp/breakpoint-locs.exp: New file. * gdb.cp/breakpoint-locs.h: New test.
2020-06-01gdb: Preserve is-stmt lines when switch between filesAndrew Burgess1-0/+7
After the is-stmt support commit: commit 8c95582da858ac981f689a6f599acacb8c5c490f Date: Mon Dec 30 21:04:51 2019 +0000 gdb: Add support for tracking the DWARF line table is-stmt field A regression was observed where a breakpoint could no longer be placed in some cases. Consider a line table like this: File 1: test.c File 2: test.h | Addr | File | Line | Stmt | |------|------|------|------| | 1 | 1 | 16 | Y | | 2 | 1 | 17 | Y | | 3 | 2 | 21 | Y | | 4 | 2 | 22 | Y | | 4 | 1 | 18 | N | | 5 | 2 | 23 | N | | 6 | 1 | 24 | Y | | 7 | 1 | END | Y | |------|------|------|------| Before the is-stmt patch GDB would ignore any non-stmt lines, so GDB built two line table structures: File 1 File 2 ------ ------ | Addr | Line | | Addr | Line | |------|------| |------|------| | 1 | 16 | | 3 | 21 | | 2 | 17 | | 4 | 22 | | 3 | END | | 6 | END | | 6 | 24 | |------|------| | 7 | END | |------|------| After the is-stmt patch GDB now records non-stmt lines, so the generated line table structures look like this: File 1 File 2 ------ ------ | Addr | Line | Stmt | | Addr | Line | Stmt | |------|------|------| |------|------|------| | 1 | 16 | Y | | 3 | 21 | Y | | 2 | 17 | Y | | 4 | 22 | Y | | 3 | END | Y | | 4 | END | Y | | 4 | 18 | N | | 5 | 23 | N | | 5 | END | Y | | 6 | END | Y | | 6 | 24 | Y | |------|------|------| | 7 | END | Y | |------|------|------| The problem is that in 'File 2', end END marker at address 4 causes the previous line table entry to be discarded, so we actually end up with this: File 2 ------ | Addr | Line | Stmt | |------|------|------| | 3 | 21 | Y | | 4 | END | Y | | 5 | 23 | N | | 6 | END | Y | |------|------|------| When a user tries to place a breakpoint in file 2 at line 22, this is no longer possible. The solution I propose here is that we ignore line table entries that would trigger a change of file if: 1. The new line being added is at the same address as the previous line, and 2. We have previously seen an is-stmt line at the current address. The result of this is that GDB switches file, and knows that some line entry (or entries) are going to be discarded, prefer to keep is-stmt lines and discard non-stmt lines. After this commit the lines tables are now: File 1 File 2 ------ ------ | Addr | Line | Stmt | | Addr | Line | Stmt | |------|------|------| |------|------|------| | 1 | 16 | Y | | 3 | 21 | Y | | 2 | 17 | Y | | 4 | 22 | Y | | 3 | END | Y | | 5 | 23 | N | | 5 | END | Y | | 6 | END | Y | | 6 | 24 | Y | |------|------|------| | 7 | END | Y | |------|------|------| We've lost the non-stmt entry for file 1, line 18, but retained the is-stmt entry for file 2, line 22. The user can now place a breakpoint at that location. One problem that came from this commit was the test gdb.cp/step-and-next-inline.exp, which broke in several places. After looking at this test again I think that in some cases this test was only ever passing by pure luck. The debug GCC is producing for this test is pretty broken. I raised this GCC bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94474 for this and disabled one entire half of the test. There are still some cases in here that do pass, and if/when GCC is fixed it would be great to enable this test again. gdb/ChangeLog: * dwarf2/read.c (class lnp_state_machine) <m_last_address>: New member variable. <m_stmt_at_address>: New member variable. (lnp_state_machine::record_line): Don't record some lines, update tracking of is_stmt at the same address. (lnp_state_machine::lnp_state_machine): Initialise new member variables. gdb/testsuite/ChangeLog: * gdb.cp/step-and-next-inline.exp (do_test): Skip all tests in the use_header case. * gdb.dwarf2/dw2-inline-header-1.exp: New file. * gdb.dwarf2/dw2-inline-header-2.exp: New file. * gdb.dwarf2/dw2-inline-header-3.exp: New file. * gdb.dwarf2/dw2-inline-header-lbls.c: New file. * gdb.dwarf2/dw2-inline-header.c: New file. * gdb.dwarf2/dw2-inline-header.h: New file.