Age | Commit message (Collapse) | Author | Files | Lines |
|
In test-case gdb.cp/nsusing.exp I came across these xfails without PRMS
mentioned:
...
XFAIL: gdb.cp/nsusing.exp: print x, before using statement
XFAIL: gdb.cp/nsusing.exp: print x, only using M
...
Add the missing PRMS, such that we have:
...
XFAIL: gdb.cp/nsusing.exp: print x, before using statement (PRMS gcc/108716)
XFAIL: gdb.cp/nsusing.exp: print x, only using M (PRMS gcc/108716)
...
and limit the xfail to unfixed versions.
The PR is fixed starting gcc 13, but it has been backported to release
branches stretching back to gcc 10. For simplicity we just stick to testing
for the major version and ignore the backported fixes.
Tested on x86_64-linux.
Approved-By: Tom Tromey <tom@tromey.com>
|
|
When running test-case gdb.cp/subtypes.exp with gcc 4.8.4, we run into:
...
FAIL: gdb.cp/subtypes.exp: ptype main::Foo
FAIL: gdb.cp/subtypes.exp: ptype main::Bar
FAIL: gdb.cp/subtypes.exp: ptype main::Baz
FAIL: gdb.cp/subtypes.exp: ptype foobar<int>::Foo
FAIL: gdb.cp/subtypes.exp: ptype foobar<int>::Bar
FAIL: gdb.cp/subtypes.exp: ptype foobar<int>::Baz
FAIL: gdb.cp/subtypes.exp: ptype foobar<char>::Foo
FAIL: gdb.cp/subtypes.exp: ptype foobar<char>::Bar
FAIL: gdb.cp/subtypes.exp: ptype foobar<char>::Baz
...
The problem is gcc PR debug/55541, which generates a superfluous
DW_TAG_lexical_block.
Add a corresponding xfail.
Tested on x86_64-linux.
|
|
Make test-case gdb.cp/subtypes.exp less repetitive by using foreach.
Tested on x86_64-linux.
|
|
When running test-cases gdb.cp/*.exp with gcc 4.8.4, I run into compilation
failures due to the test-cases requiring c++11 and the compiler defaulting
to less than that.
Fix this by compiling with -std=c++11.
This exposes two FAILs in gdb/testsuite/gdb.cp/empty-enum.exp due to
gcc PR debug/16063, so xfail those.
Also require have_compile_flag -std=c++17 in gdb.cp/constexpr-field.exp to
prevent compilation failure.
Tested on x86_64-linux.
|
|
This recent commit:
commit b1c0ab20809a502b2d2224fecb0dca3ada2e9b22
Date: Wed Jul 12 21:56:50 2023 +0100
gdb: avoid double stop after failed breakpoint condition check
Addressed a problem where two MI stopped events would be reported if a
breakpoint condition failed due to a signal, this commit was a
replacement for this commit:
commit 2e411b8c68eb2b035b31d5b00d940d4be1a0928b
Date: Fri Oct 14 14:53:15 2022 +0100
gdb: don't always print breakpoint location after failed condition check
which solved the two stop problem, but only for the CLI. Before both
of these commits, if a b/p condition failed due to a signal then the
user would see two stops reported, the first at the location where the
signal occurred, and the second at the location of the breakpoint.
By default GDB remains at the location where the signal occurred, so
the second reported stop can be confusing, this is the problem that
commit 2e411b8c68eb tried to solve (for the CLI) and b1c0ab20809a
extended also address the issue for MI too.
However, while working on another patch I realised that there was a
problem with GDB after the above commits. Neither of the above
commits considered 'set unwindonsignal on'. With this setting on,
when an inferior function call fails with a signal GDB will unwind the
stack back to the location where the inferior function call started.
In the b/p case we're looking at, the stop should be reported at the
location of the breakpoint, not at the location where the signal
occurred, and this isn't what happens.
This commit fixes this by ensuring that when unwindonsignal is 'on',
GDB reports a single stop event at the location of the breakpoint,
this fixes things for both CLI and MI.
The function call_thread_fsm::should_notify_stop is called when the
inferior function call completes and GDB is figuring out if the user
should be notified about this stop event by calling normal_stop from
fetch_inferior_event in infrun.c. If normal_stop is called, then this
notification will be for the location where the inferior call stopped,
which will be the location at which the signal occurred.
Prior to this commit, the only time that normal_stop was not called,
was if the inferior function call completed successfully, this was
controlled by ::should_notify_stop, which only turns false when the
inferior function call has completed successfully.
In this commit I have extended the logic in ::should_notify_stop. Now
there are three cases in which ::should_notify_stop will return false,
and we will not announce the first stop (by calling normal_stop).
These three reasons are:
1. If the inferior function call completes successfully, this is
unchanged behaviour,
2. If the inferior function call stopped due to a signal and 'set
unwindonsignal on' is in effect, and
3. If the inferior function call stopped due to an uncaught C++
exception, and 'set unwind-on-terminating-exception on' is in
effect.
However, if we don't call normal_stop then we need to call
async_enable_stdin in call_thread_fsm::should_stop. Prior to this
commit this was only done for the case where the inferior function
call completed successfully.
In this commit I now call ::should_notify_stop and use this to
determine if we need to call async_enable_stdin. With this done we
now call async_enable_stdin for each of the three cases listed above,
which means that GDB will exit wait_sync_command_done correctly (see
run_inferior_call in infcall.c).
With these two changes the problem is mostly resolved. However, the
solution isn't ideal, we've still lost some information.
Here is how GDB 13.1 behaves, this is before commits b1c0ab20809a and
2e411b8c68eb:
$ gdb -q /tmp/mi-condbreak-fail \
-ex 'set unwindonsignal on' \
-ex 'break 30 if (cond_fail())' \
-ex 'run'
Reading symbols from /tmp/mi-condbreak-fail...
Breakpoint 1 at 0x40111e: file /tmp/mi-condbreak-fail.c, line 30.
Starting program: /tmp/mi-condbreak-fail
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401116 in cond_fail () at /tmp/mi-condbreak-fail.c:24
24 return *p; /* Crash here. */
Error in testing breakpoint condition:
The program being debugged was signaled while in a function called from GDB.
GDB has restored the context to what it was before the call.
To change this behavior use "set unwindonsignal off".
Evaluation of the expression containing the function
(cond_fail) will be abandoned.
Breakpoint 1, foo () at /tmp/mi-condbreak-fail.c:30
30 global_counter += 1; /* Set breakpoint here. */
(gdb)
In this state we see two stop notifications, the first is where the
signal occurred, while the second is where the breakpoint is located.
As GDB has unwound the stack (thanks to unwindonsignal) the second
stop notification reflects where the inferior is actually located.
Then after commits b1c0ab20809a and 2e411b8c68eb the behaviour changed
to this:
$ gdb -q /tmp/mi-condbreak-fail \
-ex 'set unwindonsignal on' \
-ex 'break 30 if (cond_fail())' \
-ex 'run'
Reading symbols from /tmp/mi-condbreak-fail...
Breakpoint 1 at 0x40111e: file /tmp/mi-condbreak-fail.c, line 30.
Starting program: /tmp/mi-condbreak-fail
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401116 in cond_fail () at /tmp/mi-condbreak-fail.c:24
24 return *p; /* Crash here. */
Error in testing condition for breakpoint 1:
The program being debugged was signaled while in a function called from GDB.
GDB has restored the context to what it was before the call.
To change this behavior use "set unwindonsignal off".
Evaluation of the expression containing the function
(cond_fail) will be abandoned.
(gdb) bt 1
#0 foo () at /tmp/mi-condbreak-fail.c:30
(More stack frames follow...)
(gdb)
This is the broken state. GDB is reports the SIGSEGV location, but
not the unwound breakpoint location. The final 'bt 1' shows that the
inferior is not located in cond_fail, which is the only location GDB
reported, so this is clearly wrong.
After implementing the fixes described above we now get this
behaviour:
$ gdb -q /tmp/mi-condbreak-fail \
-ex 'set unwindonsignal on' \
-ex 'break 30 if (cond_fail())' \
-ex 'run'
Reading symbols from /tmp/mi-condbreak-fail...
Breakpoint 1 at 0x40111e: file /tmp/mi-condbreak-fail.c, line 30.
Starting program: /tmp/mi-condbreak-fail
Error in testing breakpoint condition for breakpoint 1:
The program being debugged was signaled while in a function called from GDB.
GDB has restored the context to what it was before the call.
To change this behavior use "set unwindonsignal off".
Evaluation of the expression containing the function
(cond_fail) will be abandoned.
Breakpoint 1, foo () at /tmp/mi-condbreak-fail.c:30
30 global_counter += 1; /* Set breakpoint here. */
(gdb)
This is better. GDB now reports a single stop at the location of the
breakpoint, which is where the inferior is actually located. However,
by removing the first stop notification we have lost some potentially
useful information about which signal caused the inferior to stop.
To address this I've reworked the message that is printed to include
the signal information. GDB now reports this:
$ gdb -q /tmp/mi-condbreak-fail \
-ex 'set unwindonsignal on' \
-ex 'break 30 if (cond_fail())' \
-ex 'run'
Reading symbols from /tmp/mi-condbreak-fail...
Breakpoint 1 at 0x40111e: file /tmp/mi-condbreak-fail.c, line 30.
Starting program: /tmp/mi-condbreak-fail
Error in testing condition for breakpoint 1:
The program being debugged received signal SIGSEGV, Segmentation fault
while in a function called from GDB. GDB has restored the context
to what it was before the call. To change this behavior use
"set unwindonsignal off". Evaluation of the expression containing
the function (cond_fail) will be abandoned.
Breakpoint 1, foo () at /tmp/mi-condbreak-fail.c:30
30 global_counter += 1; /* Set breakpoint here. */
(gdb)
This is better, the user now sees a single stop notification at the
correct location, and the error message describes which signal caused
the inferior function call to stop.
However, we have lost the information about where the signal
occurred. I did consider trying to include this information in the
error message, but, in the end, I opted not too. I wasn't sure it was
worth the effort. If the user has selected to unwind on signal, then
surely this implies they maybe aren't interested in debugging failed
inferior calls, so, hopefully, just knowing the signal name will be
enough. I figure we can always add this information in later if
there's a demand for it.
|
|
When loading an executable using "file a.out", the language is set according
to a.out, which can involve looking up the language of symbol "main", which
will cause the symtab expansion for the containing CU.
Expansion of lto debug info can be slow, so in commit d3214198119 ("[gdb] Use
partial symbol table to find language for main") a feature was added to avoid
the symtab expansion.
This feature stopped working after commit 7f4307436fd ("Fix "start" for D,
Rust, etc").
[ The commit addresses problems related to command start, which requires finding
the main function:
- for language D, "main" was found instead of "D main", and
- for Rust, the correct function was found, but attributed the wrong name
(not fully qualified). ]
Reimplement the feature by adding
cooked_index_functions::lookup_global_symbol_language.
Tested on x86_64-linux.
PR symtab/30661
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30661
|
|
This patch removes many TODOs from the gdb.cp tests.
Going through the patch:
* bs15503.exp - these have been commented out forever and rely on
libstdc++ debuginfo. It's better to just remove these.
* classes.exp - the test is wrong, I think, according to the C++ ABI
that gdb understands; and the test can be fixed and comments removed
with a simple change to the code.
* ctti.exp - there's no need to bail out any more, as the test works.
* exception.exp - the code relying on the line numbers can't work,
because gdb never prints that message anyway.
Reviewed-By: Bruno Larsen <blarsen@redhat.com>
|
|
When debugging C++ programs, it is possible to trigger a spurious assert
failure when attempting to set a breakpoint on a malformed symbol name.
Names of the form 'A>::B' and 'A)::B' trigger this assert failure in
cp_lookup_bare_symbol:
$ gdb gdb
[...]
(gdb) br test>::assert
Function "test>::assert" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (test>::assert) pending.
(gdb) start
[...]
cp-namespace.c:181: internal-error: cp_lookup_bare_symbol: Assertion `strstr (name, "::") == NULL' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
----- Backtrace -----
0x5217e2 gdb_internal_backtrace_1
/home/amerey/binutils-gdb/gdb/bt-utils.c:122
0x521885 _Z22gdb_internal_backtracev
/home/amerey/binutils-gdb/gdb/bt-utils.c:168
0xaf8303 internal_vproblem
/home/amerey/binutils-gdb/gdb/utils.c:396
0xaf86be _Z15internal_verrorPKciS0_P13__va_list_tag
/home/amerey/binutils-gdb/gdb/utils.c:476
0xccdb3f _Z18internal_error_locPKciS0_z
/home/amerey/binutils-gdb/gdbsupport/errors.cc:58
0x5dded9 cp_lookup_bare_symbol
/home/amerey/binutils-gdb/gdb/cp-namespace.c:181
0x5de39d cp_lookup_symbol_in_namespace
/home/amerey/binutils-gdb/gdb/cp-namespace.c:328
[...]
Currently this assert is skipped if the symbol name contains '<' or '('.
Fix this spurious failure by also skipping the assert when the symbol
name contains '>' or ')'.
Regression tested on F38 x86_64.
Approved-By: Tom Tromey <tom@tromey.com>
|
|
Fix a few typos:
- implemention -> implementation
- convertion(s) -> conversion(s)
- backlashes -> backslashes
- signoring -> ignoring
- (un)ambigious -> (un)ambiguous
- occured -> occurred
- hidding -> hiding
- temporarilly -> temporarily
- immediatelly -> immediately
- sillyness -> silliness
- similiar -> similar
- porkuser -> pokeuser
- thats -> that
- alway -> always
- supercede -> supersede
- accomodate -> accommodate
- aquire -> acquire
- priveleged -> privileged
- priviliged -> privileged
- priviledges -> privileges
- privilige -> privilege
- recieve -> receive
- (p)refered -> (p)referred
- succesfully -> successfully
- successfuly -> successfully
- responsability -> responsibility
- wether -> whether
- wich -> which
- disasbleable -> disableable
- descriminant -> discriminant
- construcstor -> constructor
- underlaying -> underlying
- underyling -> underlying
- structureal -> structural
- appearences -> appearances
- terciarily -> tertiarily
- resgisters -> registers
- reacheable -> reachable
- likelyhood -> likelihood
- intepreter -> interpreter
- disassemly -> disassembly
- covnersion -> conversion
- conviently -> conveniently
- atttribute -> attribute
- struction -> struct
- resonable -> reasonable
- popupated -> populated
- namespaxe -> namespace
- intialize -> initialize
- identifer(s) -> identifier(s)
- expection -> exception
- exectuted -> executed
- dungerous -> dangerous
- dissapear -> disappear
- completly -> completely
- (inter)changable -> (inter)changeable
- beakpoint -> breakpoint
- automativ -> automatic
- alocating -> allocating
- agressive -> aggressive
- writting -> writing
- reguires -> requires
- registed -> registered
- recuding -> reducing
- opeartor -> operator
- ommitted -> omitted
- modifing -> modifying
- intances -> instances
- imbedded -> embedded
- gdbaarch -> gdbarch
- exection -> execution
- direcive -> directive
- demanged -> demangled
- decidely -> decidedly
- argments -> arguments
- agrument -> argument
- amespace -> namespace
- targtet -> target
- supress(ed) -> suppress(ed)
- startum -> stratum
- squence -> sequence
- prompty -> prompt
- overlow -> overflow
- memember -> member
- languge -> language
- geneate -> generate
- funcion -> function
- exising -> existing
- dinking -> syncing
- destroh -> destroy
- clenaed -> cleaned
- changep -> changedp (name of variable)
- arround -> around
- aproach -> approach
- whould -> would
- symobl -> symbol
- recuse -> recurse
- outter -> outer
- freeds -> frees
- contex -> context
Tested on x86_64-linux.
Reviewed-By: Tom Tromey <tom@tromey.com>
|
|
This commit makes two changes to how we match newline characters in
the gdb_test proc.
First, for the newline pattern between the command output and the
prompt, I propose changing from '[\r\n]+' to an explicit '\r\n'.
The old pattern would spot multiple newlines, and so there are a few
places where, as part of this commit, I've needed to add an extra
trailing '\r\n' to the pattern in the main test file, where GDB's
output actually includes a blank line.
But I think this is a good thing. If a command produces a blank line
then we should be checking for it, the current gdb_test doesn't do
that. But also, with the current gdb_test, if a blank line suddenly
appears in the output, this is going to be silently ignored, and I
think this is wrong, the test should fail in that case.
Additionally, the existing pattern will happily match a partial
newline. There are a strangely large number of tests that end with a
random '.' character. Not matching a literal period, but matching any
single character, this is then matching half of the trailing newline
sequence, while the \[\r\n\]+ in gdb_test is matching the other half
of the sequence. I can think of no reason why this would be
intentional, I suspect that the expected output at one time included a
period, which has since been remove, but I haven't bothered to check
on this. In this commit I've removed all these unneeded trailing '.'
characters.
The basic rule of gdb_test after this is that the expected pattern
needs to match everything up to, but not including the newline
sequence immediately before the GDB prompt. This is generally how the
proc is used anyway, so in almost all cases, this commit represents no
significant change.
Second, while I was cleaning up newline matching in gdb_test, I've
also removed the '[\r\n]*' that was added to the start of the pattern
passed to gdb_test_multiple.
The addition of this pattern adds no value. If the user pattern
matches at the start of a line then this would match against the
newline sequence. But, due to the '*', if the user pattern doesn't
match at the start of a line then this group doesn't care, it'll
happily match nothing.
As such, there's no value to it, it just adds more complexity for no
gain, so I'm removing it. No tests will need updating as a
consequence of this part of the patch.
Reviewed-By: Tom Tromey <tom@tromey.com>
|
|
Since commit 6d263fe46e0 ("Avoid bad breakpoints with --gc-sections"), there
was a silent regression on openSUSE Leap 15.4 for test-case
gdb.cp/m-static.exp, from:
...
(gdb) info variable everywhere^M
All variables matching regular expression "everywhere":^M
^M
File /home/vries/tmp.local-remote-host-native/m-static.h:^M
8: const int gnu_obj_4::everywhere;^M
(gdb)
...
to:
...
(gdb) info variable everywhere^M
All variables matching regular expression "everywhere":^M
^M
File /data/vries/gdb/src/gdb/testsuite/gdb.cp/m-static.h:^M
8: const int gnu_obj_4::everywhere;^M
^M
File /data/vries/gdb/src/gdb/testsuite/gdb.cp/m-static1.cc:^M
8: const int gnu_obj_4::everywhere;^M
(gdb)
...
Another regression was found due to that commit, and it was fixed in commit
99d679e7b30 ("[gdb/symtab] Fix "file index out of range" complaint") by
limiting the scope of the fix in the original commit.
Fix this regression by yet further limiting the scope of that fix, making sure
that this bit in dwarf_decode_lines is executed again for m-static1.cc:
...
/* Make sure a symtab is created for every file, even files
which contain only variables (i.e. no code with associated
line numbers). */
...
Tested on x86_64-linux.
PR symtab/30265
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30265
|
|
In commit 722c4596034 ("[gdb/testsuite] Fix gdb.cp/*.exp for remote host"), I
needed to change ".*/" into "(.*/)?" in:
...
gdb_test "info variable everywhere" \
"File .*/m-static\[.\]h.*const int gnu_obj_4::everywhere;"
...
However, due to the fact that I got this output:
...
(gdb) info variable everywhere^M
All variables matching regular expression "everywhere":^M
^M
File /data/vries/gdb/src/gdb/testsuite/gdb.cp/m-static.h:^M
8: const int gnu_obj_4::everywhere;^M
^M
File /data/vries/gdb/src/gdb/testsuite/gdb.cp/m-static1.cc:^M
8: const int gnu_obj_4::everywhere;^M
...
I decided to make the matching somewhat stricter, to make sure that the two
matched lines were subsequent.
The commit turned out to be more strict than intended, and caused a regression
on Ubuntu 20.04, where the output was instead:
...
(gdb) info variable everywhere^M
All variables matching regular expression "everywhere":^M
^M
File /data/vries/gdb/src/gdb/testsuite/gdb.cp/m-static.h:^M
8: const int gnu_obj_4::everywhere;^M
...
At that point I realized I'm looking at a bug (filed as PR symtab/30265),
which manifests on openSUSE Leap 15.4 for native and readnow, and on Ubuntu
20.04 for readnow, but not for native.
Before my commit, the test-case passed whether the bug manifested or not.
After my commit, the test-case only passed when the bug manifested.
Fix the test-case regression by reverting to the situation before the commit:
pass whether the bug manifests or not. We could add an xfail for the PR, but
I'm expecting a fix soon, so that doesn't look worth the effort.
Tested on x86_64-linux, both on openSUSE Leap 15.4 and Ubuntu 20.04, both with
native and readnow.
Reported-By: Simon Marchi <simon.marchi@efficios.com>
|
|
Fix test-case gdb.cp/cp-relocate.exp for remote host using
gdb_remote_download.
Tested on x86_64-linux.
|
|
When running test-cases gdb.cp/annota{2,3}.exp with target board
native-extended-gdbserver, we run into a few FAILs, due to the test-cases
trying to match inferior output together with gdb output.
Fix this by ignoring the inferior output in this case.
Tested on x86_64-linux.
|
|
Fix a few test-cases in gdb.cp/*.exp for remote host using new proc
include_file.
Tested on x86_64-linux.
|
|
In some cases GDB will fail when attempting to complete a command that
involves a rust symbol, the failure can manifest as a crash.
The problem is caused by the completion_match_for_lcd object being
left containing invalid data during calls to cp_symbol_name_matches_1.
The first question to address is why we are calling a C++ support
function when handling a rust symbol. That's due to GDB's auto
language detection for msymbols, in some cases GDB can't tell if a
symbol is a rust symbol, or a C++ symbol.
The test application contains symbols for functions which are
statically linked in from various rust support libraries. There's no
DWARF for these symbols, so all GDB has is the msymbols built from the
ELF symbol table.
Here's the problematic symbol that leads to our crash:
mangled: _ZN4core3str21_$LT$impl$u20$str$GT$5parse17h5111d2d6a50d22bdE
demangled: core::str::<impl str>::parse
As an msymbol this is initially created with language auto, then GDB
eventually calls symbol_find_demangled_name, which loops over all
languages calling language_defn::sniff_from_mangled_name, the first
language that can demangle the symbol gets assigned as the language
for that symbol.
Unfortunately, there's overlap in the mangled symbol names,
some (legacy) rust symbols can be demangled as both rust and C++, see
cplus_demangle in libiberty/cplus-dem.c where this is mentioned.
And so, because we check the C++ language before we check for rust,
then the msymbol is (incorrectly) given the C++ language.
Now it's true that is some cases we might be able to figure out that a
demangled symbol is not actually a valid C++ symbol, for example, in
our case, the construct '::<impl str>::' is not, I believe, valid in a
C++ symbol, we could look for ':<' and '>:' and refuse to accept this
as a C++ symbol.
However, I'm not sure it is always possible to tell that a demangled
symbol is rust or C++, so, I think, we have to accept that some times
we will get this language detection wrong.
If we accept that we can't fix the symbol language detection 100% of
the time, then we should make sure that GDB doesn't crash when it gets
the language wrong, that is what this commit addresses.
In our test case the user tries to complete a symbol name like this:
(gdb) complete break pars
This results in GDB trying to find all symbols that match 'pars',
eventually we consider our problematic symbol, and we end up with a
call stack that looks like this:
#0 0x0000000000f3c6bd in strncmp_iw_with_mode
#1 0x0000000000706d8d in cp_symbol_name_matches_1
#2 0x0000000000706fa4 in cp_symbol_name_matches
#3 0x0000000000df3c45 in compare_symbol_name
#4 0x0000000000df3c91 in completion_list_add_name
#5 0x0000000000df3f1d in completion_list_add_msymbol
#6 0x0000000000df4c94 in default_collect_symbol_completion_matches_break_on
#7 0x0000000000658c08 in language_defn::collect_symbol_completion_matches
#8 0x0000000000df54c9 in collect_symbol_completion_matches
#9 0x00000000009d98fb in linespec_complete_function
#10 0x00000000009d99f0 in complete_linespec_component
#11 0x00000000009da200 in linespec_complete
#12 0x00000000006e4132 in complete_address_and_linespec_locations
#13 0x00000000006e4ac3 in location_completer
In cp_symbol_name_matches_1 we enter a loop, this loop repeatedly
tries to match the demangled problematic symbol name against the user
supplied text ('pars'). Each time around the loop another component
of the symbol name is stripped off, thus, we check 'pars' against
these options:
core::str::<impl str>::parse
str::<impl str>::parse
<impl str>::parse
parse
As soon as we get a match the cp_symbol_name_matches_1 exits its loop
and returns. In our case, when we're looking for 'pars', the match
occurs on the last iteration of the loop, when we are comparing to
'parse'.
Now the problem here is that cp_symbol_name_matches_1 uses the
strncmp_iw_with_mode, and inside strncmp_iw_with_mode we allow for
skipping over template parameters. This allows GDB to match the
symbol name 'foo<int>(int,int)' if the user supplies 'foo(int,'.
Inside strncmp_iw_with_mode GDB will record any template arguments
that it has skipped over inside the completion_match_for_lcd object
that is passed in as an argument.
And so, when GDB tries to match against '<impl str>::parse', the first
thing it sees is '<impl str>', GDB assumes this is a template argument
and records this as a skipped region within the
completion_match_for_lcd object. After '<impl str>' GDB sees a ':'
character, which doesn't match with the 'pars' the user supplied, so
strncmp_iw_with_mode returns a value indicating a non-match. GDB then
removes the '<impl str>' component from the symbol name and tries
again, this time comparing to 'parse', which does match.
Having found a match, then in cp_symbol_name_matches_1 we record the
match string, and the full symbol name within the
completion_match_result object, and return.
The problem here is that the skipped region, the '<impl str>' that we
recorded in the penultimate loop iteration was never discarded, its
still there in our returned result.
If we look at what the pointers held in the completion_match_result
that cp_symbol_name_matches_1 returns, this is what we see:
core::str::<impl str>::parse
| \________/ |
| | '--- completion match string
| '---skip range
'--- full symbol name
When GDB calls completion_match_for_lcd::finish, GDB tries to create a
string using the completion match string (parse), but excluding the
skip range, as the stored skip range is before the start of the
completion match string, then GDB tries to do some weird string
creation, which will cause GDB to crash.
The reason we don't often see this problem in C++ is that for C++
symbols there is always some non-template text before the template
argument. This non-template text means GDB is likely to either match
the symbol, or reject the symbol without storing a skip range.
However, notice, I did say, we don't often see this problem. Once I
understood the issue, I was able to reproduce the crash using a pure
C++ example:
template<typename S>
struct foo
{
template<typename T>
foo (int p1, T a)
{
s = 0;
}
S s;
};
int
main ()
{
foo<int> obj (2.3, 0);
return 0;
}
Then in GDB:
(gdb) complete break foo(int
The problem here is that the C++ symbol for the constructor looks like
this:
foo<int>::foo<double>(int, double)
When GDB enters cp_symbol_name_matches_1 the symbols it examines are:
foo<int>::foo<double>(int, double)
foo<double>(int, double)
The first iteration of the loop will match the 'foo', then add the
'<int>' template argument will be added as a skip range. When GDB
find the ':' after the '<int>' the first iteration of the loop fails
to match, GDB removes the 'foo<int>::' component, and starts the
second iteration of the loop.
Again, GDB matches the 'foo', and now adds '<double>' as a skip
region. After that the '(int' successfully matches, and so the second
iteration of the loop succeeds, but, once again we left the '<int>' in
place as a skip region, even though this occurs before the start of
our match string, and this will cause GDB to crash.
This problem was reported to the mailing list, and a solution
discussed in this thread:
https://sourceware.org/pipermail/gdb-patches/2023-January/195166.html
The solution proposed here is similar to one proposed by the original
bug reported, but implemented in a different location within GDB.
Instead of placing the fix in strncmp_iw_with_mode, I place the fix in
cp_symbol_name_matches_1. I believe this is a better location as it
is this function that implements the loop, and it is this loop, which
repeatedly calls strncmp_iw_with_mode, that should be resetting the
result object state (I believe).
What I have done is add an assert to strncmp_iw_with_mode that the
incoming result object is empty.
I've also added some other asserts in related code, in
completion_match_for_lcd::mark_ignored_range, I make some basic
assertions about the incoming range pointers, and in
completion_match_for_lcd::finish I also make some assertions about how
the skip ranges relate to the match pointer.
There's two new tests. The original rust example that was used in the
initial bug report, and a C++ test. The rust example depends on which
symbols are pulled in from the rust libraries, so it is possible that,
at some future date, the problematic symbol will disappear from this
test program. The C++ test should be more reliable, as this only
depends on symbols from within the C++ source code.
Since I originally posted this patch to the mailing list, the
following patch has been merged:
commit 6e7eef72164c00d6a5a7b0bce9fa01f5481f33cb
Date: Sun Mar 19 09:13:10 2023 -0600
Use rust_demangle to fix a crash
This solves the problem of a rust symbol ending up in the C++ specific
code by changing the order languages are sorted. However, this new
commit doesn't address the issue in the C++ code which was fixed with
this commit.
Given that the C++ issue is real, and has a reproducer, I'm still
going to merge this fix. I've left the discussion of rust in this
commit message as I originally wrote it, but it should be read within
the context of GDB prior to commit 6e7eef72164c00d6a5a7.
Co-Authored-By: Zheng Zhan <zzlossdev@163.com>
|
|
Handle $srcdir/lib/attributes.h using lappend_include_dir.
Tested on x86_64-linux.
|
|
This changes many tests to use 'require' when checking target_info.
In a few spots, the require is hoisted to the top of the file, to
avoid doing any extra work when the test is going to be skipped
anyway.
|
|
remote-gdbserver-on-localhost
Test-case gdb.cp/breakpoint-shlib-func.exp fails with target board
remote-gdbserver-on-localhost.
Fix this by adding the missing gdb_load_shlib.
Tested on x86_64-linux.
|
|
In C++ it is possible to use an empty enum as a strong typedef. For
example, a user could write:
enum class my_type : unsigned char {};
Now my_type can be used like 'unsigned char' except the compiler will
not allow implicit conversion too and from the native 'unsigned char'
type.
This is used in the standard library for things like std::byte.
Currently, when GDB prints a value of type my_type, it looks like
this:
(gdb) print my_var
$1 = (unknown: 0x4)
Which isn't great. This gets worse when we consider something like:
std::vector<my_type> vec;
When using a pretty-printer, this could look like this:
std::vector of length 2, capacity 2 = {(unknown: 0x2), (unknown: 0x4)}
Clearly not great. This is described in PR gdb/30148.
The problem here is in dwarf2/read.c, we assume all enums are flag
enums unless we find an enumerator with a non-flag like value.
Clearly an empty enum contains no non-flag values, so we assume the
enum is a flag enum.
I propose adding an extra check here; that is, an empty enum should
never be a flag enum.
With this the above cases look more like:
(gdb) print my_var
$1 = 4
and:
std::vector of length 2, capacity 2 = {2, 4}
Which look much better.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30148
Reviewed-By: Tom Tromey <tom@tromey.com>
|
|
This commit should fix PR gdb/20091, PR gdb/17201, and PR gdb/17071.
Additionally, PR gdb/17199 relates to this area of code, but is more
of a request to refactor some parts of GDB, this commit does not
address that request, but it is probably worth reading that PR when
looking at this commit.
When the current language is C++, and the user places a breakpoint on
a function in a shared library, GDB will currently find two locations
for the breakpoint, one location will be within the function itself as
we would expect, but the other location will be within the PLT table
for the call to the named function. Consider this session:
$ gdb -q /tmp/breakpoint-shlib-func
Reading symbols from /tmp/breakpoint-shlib-func...
(gdb) start
Temporary breakpoint 1 at 0x40112e: file /tmp/breakpoint-shlib-func.cc, line 20.
Starting program: /tmp/breakpoint-shlib-func
Temporary breakpoint 1, main () at /tmp/breakpoint-shlib-func.cc:20
20 int answer = foo ();
(gdb) break foo
Breakpoint 2 at 0x401030 (2 locations)
(gdb) info breakpoints
Num Type Disp Enb Address What
2 breakpoint keep y <MULTIPLE>
2.1 y 0x0000000000401030 <foo()@plt>
2.2 y 0x00007ffff7fc50fd in foo() at /tmp/breakpoint-shlib-func-lib.cc:20
This is not the expected behaviour. If we compile the same test using
a C compiler then we see this:
(gdb) break foo
Breakpoint 2 at 0x7ffff7fc50fd: file /tmp/breakpoint-shlib-func-c-lib.c, line 20.
(gdb) info breakpoints
Num Type Disp Enb Address What
2 breakpoint keep y 0x00007ffff7fc50fd in foo at /tmp/breakpoint-shlib-func-c-lib.c:20
Here's what's happening. When GDB parses the symbols in the main
executable and the shared library we see a number of different symbols
for foo, and use these to create entries in GDB's msymbol table:
- In the main executable we see a symbol 'foo@plt' that points at
the plt entry for foo, from this we add two entries into GDB's
msymbol table, one called 'foo@plt' which points at the plt entry
and has type mst_text, then we create a second symbol, this time
called 'foo' with type mst_solib_trampoline which also points at
the plt entry,
- Then, when the shared library is loaded we see another symbol
called 'foo', this one points at the actual implementation in the
shared library. This time GDB creates a msymbol called 'foo' with
type mst_text that points at the implementation.
This means that GDB creates 3 msymbols to represent the 2 symbols
found in the executable and shared library.
When the user creates a breakpoint on 'foo' GDB eventually ends up in
search_minsyms_for_name (linespec.c), this function then calls
iterate_over_minimal_symbols passing in the name we are looking for
wrapped in a lookup_name_info object.
In iterate_over_minimal_symbols we iterate over two hash tables (using
the name we're looking for as the hash key), first we walk the hash
table of symbol linkage names, then we walk the hash table of
demangled symbol names.
When the language is C++ the symbols for 'foo' will all have been
mangled, as a result, in this case, the iteration of the linkage name
hash table will find no matching results.
However, when we walk the demangled hash table we do find some
results. In order to match symbol names, GDB obtains a symbol name
matching function by calling the get_symbol_name_matcher method on the
language_defn class. For C++, in this case, the matching function we
use is cp_fq_symbol_name_matches, which delegates the work to
strncmp_iw_with_mode with mode strncmp_iw_mode::MATCH_PARAMS and
language set to language_cplus.
The strncmp_iw_mode::MATCH_PARAMS mode means that strncmp_iw_mode will
skip any parameters in the demangled symbol name when checking for a
match, e.g. 'foo' will match the demangled name 'foo()'. The way this
is done is that the strings are matched character by character, but,
once the string we are looking for ('foo' here) is exhausted, if we
are looking at '(' then we consider the match a success.
Lets consider the 3 symbols GDB created. If the function declaration
is 'void foo ()' then from the main executable we added symbols
'_Z3foov@plt' and '_Z3foov', while from the shared library we added
another symbol call '_Z3foov'. When these are demangled they become
'foo()@plt', 'foo()', and 'foo()' respectively.
Now, the '_Z3foov' symbol from the main executable has the type
mst_solib_trampoline, and in search_minsyms_for_name, we search for
any symbols of type mst_solib_trampoline and filter these out of the
results.
However, the '_Z3foov@plt' symbol (from the main executable), and the
'_Z3foov' symbol (from the shared library) both have type mst_text.
During the demangled name matching, due to the use of MATCH_PARAMS
mode, we stop the comparison as soon as we hit a '(' in the demangled
name. And so, '_Z3foov@plt', which demangles to 'foo()@plt' matches
'foo', and '_Z3foov', which demangles to 'foo()' also matches 'foo'.
By contrast, for C, there are no demangled hash table entries to be
iterated over (in iterate_over_minimal_symbols), we only consider the
linkage name symbols which are 'foo@plt' and 'foo'. The plain 'foo'
symbol obviously matches when we are looking for 'foo', but in this
case the 'foo@plt' will not match due to the '@plt' suffix.
And so, when the user asks for a breakpoint in 'foo', and the language
is C, search_minsyms_for_name, returns a single msymbol, the mst_text
symbol for foo in the shared library, while, when the language is C++,
we get two results, '_Z3foov' for the shared library function, and
'_Z3foov@plt' for the plt entry in the main executable.
I propose to fix this in strncmp_iw_with_mode. When the mode is
MATCH_PARAMS, instead of stopping at a '(' and assuming the match is a
success, GDB will instead search forward for the matching, closing,
')', effectively skipping the parameter list, and then resume
matching. Thus, when comparing 'foo' to 'foo()@plt' GDB will
effectively compare against 'foo@plt' (skipping the parameter list),
and the match will fail, just as it does when the language is C.
There is one slight complication, which is revealed by the test
gdb.linespec/cpcompletion.exp, when searching for the symbol of a
const member function, the demangled symbol will have 'const' at the
end of its name, e.g.:
struct_with_const_overload::const_overload_fn() const
Previously, the matching would stop at the '(' character, but after my
change the whole '()' is skipped, and the match resumes. As a result,
the 'const' modifier results in a failure to match, when previously
GDB would have found a match.
To work around this issue, in strncmp_iw_with_mode, when mode is
MATCH_PARAMS, after skipping the parameter list, if the next character
is '@' then we assume we are looking at something like '@plt' and
return a value indicating the match failed, otherwise, we return a
value indicating the match succeeded, this allows things like 'const'
to be skipped.
With these changes in place I now see GDB correctly setting a
breakpoint only at the implementation of 'foo' in the shared library.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=20091
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=17201
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=17071
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=17199
Tested-By: Bruno Larsen <blarsen@redhat.com>
Approved-By: Simon Marchi <simon.marchi@efficios.com>
|
|
Change gdb.cp to use clean_restart more consistently.
|
|
A number of tests end with "return". However, this is unnecessary.
This patch removes all of these.
|
|
Due to a GDB bug (visible when building with -D_GLIBCXX_DEBUG), GDB
crashes somewhere in the middle of gdb.cp/cpexprs.exp, and thus fails to
read the string, at gdb.cp/cpexprs.exp.tcl:725. The "correct" variable
doesn't get set, and I then see this TCL error:
ERROR: can't read "correct": no such variable
Avoid the TCL error by initializing the "correct" variable to a dummy
value.
Change-Id: I828968d9b2d105ef47f8da2ef598aa16a518c059
|
|
Add new proc is_x86_64_m64_target and use it where appropriate.
Tested on x86_64-linux.
|
|
The previous commit touched the source file for the test script
gdb.cp/cpcompletion.exp. This source file is called pr9594.cc. The
source file is only used by the one test script.
This commit renames the source file to cpcompletion.cc to match the
test script, this is more inline with how we name source files these
days.
|
|
Spotted in gdb.cp/cpcompletion.exp that we could replace some uses of
gdb_test with test_gdb_complete_unique, this will extend the
completion testing to check tab-completion as well as completion using
the 'complete' command in some additional cases.
|
|
While looking at some test output, I saw that no-libstdcxx-probe.exp
was not being run. However, it occurred to me that Tom de Vries' new
"maint ignore-probes" command could be used to enable this test
unconditionally.
Reviewed-by: Tom de Vries <tdevries@suse.de>
|
|
The new paramless.exp test was not converted to the new "require"
approach. This patch fixes the problem.
|
|
PR c++/29896 points out a regression in the new DWARF reader. It does
not properly handle a case like "break fn", where "fn" is a template
function.
This happens because the new index uses strncasecmp to compare.
However, to make this work correctly, we need a custom function that
ignores template parameters.
This patch adds a custom comparison function and fixes the bug. A new
test case is included.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29896
|
|
This changes skip_shlib_tests to invert the sense, and renames it to
allow_shlib_tests.
|
|
This changes skip_hw_watchpoint_tests to invert the sense, and renames
it to allow_hw_watchpoint_tests.
|
|
This changes skip_cplus_tests to invert the sense, and renames it to
allow_cplus_tests. This one also converts skip_stl_tests to
allow_stl_tests, as that was convenient to do at the same time.
|
|
This changes some tests to use "require target_can_use_run_cmd".
|
|
This changes some tests to use "require !skip_stl_tests".
|
|
This changes some tests to use "require !skip_shlib_tests".
|
|
This changes some tests to use "require !skip_cplus_tests".
|
|
This changes some tests to use "require dwarf2_support".
|
|
PR c++/29503 points out that something like "b->Base::member" will
crash when 'b' does not have pointer type. This seems to be a simple
oversight in eval_op_member.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29503
Reviewed-By: Bruno Larsen <blarsen@redhat.com>
|
|
When running gdb.cp/nsusing.cc and stopping at line 17, we can ask GDB
to print x and get a compiler-dependent answer. Using gcc 12.2.1, GDB
will print M::x, and using clang 16.0.0 prints N::x. Not only is this
behavior confusing to users, it is also not consistent with compiler
behaviors, which would warn that using x is ambiguous at this point.
This commit makes GDB behavior consistent with compilers. it achieves
this by making it so instead of exiting early when finding any symbol
with the correct name, GDB continues searching through all include
directives, storing all matching symbols in a relational map betwen the
mangled name and the found symbols.
If the resulting map has more than one entry, GDB says that the
reference is ambiguous and lists all possibilities. Otherwise it returns
the block_symbol structure for the desired symbol, or an empty struct if
nothing was found.
The commit also changes gdb.cp/nsusing.exp to test the ambiguous
detection.
|
|
This commit is the result of running the gdb/copyright.py script,
which automated the update of the copyright year range for all
source files managed by the GDB project to be updated to include
year 2023.
|
|
On Ubuntu 22.04.1 x86_64, I run into:
...
(gdb) PASS: gdb.cp/step-and-next-inline.exp: no_header: not in inline 1
next^M
51 if (t != NULL^M
(gdb) FAIL: gdb.cp/step-and-next-inline.exp: no_header: next step 1
...
This is due to -fcf-protection, which adds the endbr64 at the start of get_alias_set:
...
0000000000001180 <_Z13get_alias_setP4tree>:
1180: f3 0f 1e fa endbr64
1184: 48 85 ff test %rdi,%rdi
...
so the extra insn gets an is-stmt line number entry:
...
INDEX LINE ADDRESS IS-STMT PROLOGUE-END
...
11 50 0x0000000000001180 Y
12 50 0x0000000000001180
13 51 0x0000000000001184 Y
14 54 0x0000000000001184
...
and when stepping into get_alias_set we step to line 50:
...
(gdb) PASS: gdb.cp/step-and-next-inline.exp: no_header: in main
step^M
get_alias_set (t=t@entry=0x555555558018 <xx>) at step-and-next-inline.cc:50^M
50 {^M
...
In contrast, with -fcf-protection=none, we get:
...
0000000000001170 <_Z13get_alias_setP4tree>:
1170: 48 85 ff test %rdi,%rdi
...
and:
...
INDEX LINE ADDRESS IS-STMT PROLOGUE-END
...
11 50 0x0000000000001170 Y
12 51 0x0000000000001170 Y
13 54 0x0000000000001170
...
so when stepping into get_alias_set we step to line 51:
...
(gdb) PASS: gdb.cp/step-and-next-inline.exp: no_header: in main
step^M
get_alias_set (t=t@entry=0x555555558018 <xx>) at step-and-next-inline.cc:51^M
51 if (t != NULL^M
...
Fix this by rewriting the gdb_test issuing the step command to check which
line the step lands on, and issuing an extra next if needed.
Tested on x86_64-linux, both with and without -fcf-protection=none.
PR testsuite/29920
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29920
|
|
When asking GDB to print a variable from an imported namespace, we only
want to see variables imported in lines that the inferior has already
gone through, as is being tested last in gdb.cp/nsusing.exp. However
with the proposed change to gdb.cp/nsusing.exp, we get the following
failures:
(gdb) PASS: gdb.cp/nsusing.exp: continue to breakpoint: marker10 stop
print x
$9 = 911
(gdb) FAIL: gdb.cp/nsusing.exp: print x, before using statement
next
15 y += x;
(gdb) PASS: gdb.cp/nsusing.exp: using namespace M
print x
$10 = 911
(gdb) PASS: gdb.cp/nsusing.exp: print x, only using M
Showing that the feature wasn't functioning properly, it just so
happened that gcc ordered the namespaces in a convenient way.
This happens because GDB doesn't take into account the line where the
"using namespace" directive is written. So long as it shows up in the
current scope, we assume it is valid.
To fix this, add a new member to struct using_direct, that stores the
line where the directive was written, and a new function that informs if
the using directive is valid already.
Unfortunately, due to a GCC bug, the failure still shows up. Compilers
that set the declaration line of the using directive correctly (such as
Clang) do not show such a bug, so the test includes an XFAIL for gcc
code.
Finally, because the final test of gdb.cp/nsusing.exp has turned into
multiple that all would need XFAILs for older GCCs (<= 4.3), and that
GCC is very old, if it is detected, the test just exits early.
Approved-by: Tom Tromey <tom@tromey.com>
|
|
I noticed that when running these two tests in sequence:
Running /home/smarchi/src/binutils-gdb/gdb/testsuite/gdb.ada/arrayptr.exp ...
ERROR: GDB process no longer exists
ERROR: Couldn't run foo-all
Running /home/smarchi/src/binutils-gdb/gdb/testsuite/gdb.ada/assign_1.exp ...
The results in gdb.sum are:
Running /home/smarchi/src/binutils-gdb/gdb/testsuite/gdb.ada/arrayptr.exp ...
PASS: gdb.ada/arrayptr.exp: scenario=all: compilation foo.adb
ERROR: GDB process no longer exists
UNRESOLVED: gdb.ada/arrayptr.exp: scenario=all: gdb_breakpoint: set breakpoint at foo.adb:40 (eof)
ERROR: Couldn't run foo-all
Running /home/smarchi/src/binutils-gdb/gdb/testsuite/gdb.ada/assign_1.exp ...
UNRESOLVED: gdb.ada/assign_1.exp: changing the language to ada
PASS: gdb.ada/assign_1.exp: set convenience variable $xxx to 1
The UNRESOLVED for arrayptr.exp is fine, as GDB crashes in that test,
while trying to run to main. However, the UNRESOLVED in assign_1.exp
doesn't make sense, GDB behaves as expected in that test:
(gdb) set lang ada^M
(gdb) UNRESOLVED: gdb.ada/assign_1.exp: changing the language to ada
print $xxx := 1^M
$1 = 1^M
(gdb) PASS: gdb.ada/assign_1.exp: set convenience variable $xxx to 1
The problem is that arrayptr.exp calls perror when failing to run to
main, then returns. perror makes it so that the next test (as in
pass/fail) will be recorded as UNRESOLVED. However, here, the next test
(as in pass/fail) is in the next test (as in .exp). Hence the spurious
UNRESOLVED in assign_1.exp.
These perror when failing to run to X are not really useful, especially
since runto records a FAIL on error, by default. Remove all the
perrors on runto failure I could find.
When there wasn't one already, add a return statement when failing to
run, to avoid running the test of the test unnecessarily.
I thought of adding a check ran between test (in gdb_finish
probably) where we would emit a warning if errcnt > 0, meaning a test
quit and left a perror "active". However, reading that variable would
poke into the DejaGNU internals, not sure it's a good idea.
Change-Id: I2203df6d06e199540b36f56470d1c5f1dc988f7b
|
|
The canonical form of 'if' in modern TCL is 'if {} {}'. But there's
still a bunch of places in the testsuite where we make use of the
'then' keyword, and sometimes these get copies into new tests, which
just spreads poor practice.
This commit removes all use of the 'then' keyword from the gdb.cp/
test script directory.
There should be no changes in what is tested after this commit.
|
|
$_hit_locno PR breakpoints/12464
This implements the request given in PR breakpoints/12464.
Before this patch, when a breakpoint that has multiple locations is reached,
GDB printed:
Thread 1 "zeoes" hit Breakpoint 1, some_func () at somefunc1.c:5
This patch changes the message so that bkpt_print_id prints the precise
encountered breakpoint:
Thread 1 "zeoes" hit Breakpoint 1.2, some_func () at somefunc1.c:5
In mi mode, bkpt_print_id also (optionally) prints a new table field "locno":
locno is printed when the breakpoint hit has more than one location.
Note that according to the GDB user manual node 'GDB/MI Development and Front
Ends', it is ok to add new fields without changing the MI version.
Also, when a breakpoint is reached, the convenience variables
$_hit_bpnum and $_hit_locno are set to the encountered breakpoint number
and location number.
$_hit_bpnum and $_hit_locno can a.o. be used in the command list of a
breakpoint, to disable the specific encountered breakpoint, e.g.
disable $_hit_bpnum.$_hit_locno
In case the breakpoint has only one location, $_hit_locno is set to
the value 1, so as to allow a command such as:
disable $_hit_bpnum.$_hit_locno
to disable the breakpoint even when the breakpoint has only one location.
This also fixes a strange behaviour: when a breakpoint X has only
one location,
enable|disable X.1
is accepted but transforms the breakpoint in a multiple locations
breakpoint having only one location.
The changes in RFA v4 handle the comments of Tom Tromey:
- Changed convenience var names from $bkptno/$locno to
$_hit_bpnum/$_hit_locno.
- updated the tests and user manual accordingly.
User manual also explictly describes that $_hit_locno is set to 1
for a breakpoint with a single location.
- The variable values are now set in bpstat_do_actions_1 so that
they are set for silent breakpoints, and when several breakpoints
are hit at the same time, that the variables are set to the printed
breakpoint.
The changes in RFA v3 handle the additional comments of Eli:
GDB/NEW:
- Use max 80-column
- Use 'code location' instead of 'location'.
- Fix typo $bkpno
- Ensure that disable $bkptno and disable $bkptno.$locno have
each their explanation inthe example
- Reworded the 'breakpoint-hit' paragraph.
gdb.texinfo:
- Use 'code location' instead of 'location'.
- Add a note to clarify the distinction between $bkptno and $bpnum.
- Use @kbd instead of examples with only one command.
Compared to RFA v1, the changes in v2 handle the comments given by
Keith Seitz and Eli Zaretskii:
- Use %s for the result of paddress
- Use bkptno_numopt_re instead of 2 different -re cases
- use C@t{++}
- Add index entries for $bkptno and $locno
- Added an example for "locno" in the mi interface
- Added examples in the Break command manual.
|
|
Convert the gdb.cp/call-method-register.exp test to make use of the
DWARF assembler.
The existing gdb.cp/call-method-register.exp test relies on a GCC
extension - forcing a local variable into a particular named register.
This means that the test will only work with Clang, and, as we have to
name the register into which the variable will be placed, will only
work for those targets where we've selected a suitable register,
currently this is x86-64, i386, and ppc64.
By switching to the DWARF assembler, the test will work with gcc and
clang, and should work on most, if not all, architectures.
The test creates a small structure, something that can fit within a
register, and then tries to call a method on the structure from within
GDB. This should fail because GDB can't take the address of the in
register structure (for the `this` pointer).
As the test is for a failure case, then we don't really care _which_
register the structure is in, and I take advantage of this for the
DWARF assembler test, I just declare that the variable is in
DW_OP_reg0, whatever that might be. I've tested the new test on
x86-64, ppc, aarch64, and risc-v, and the test runs, and passes on all
these architectures, which is already more than we used to cover.
Additionally, on x86-64, I've tested with Clang and gcc, and the test
runs and passed with both compilers.
Reviewed-By: Lancelot SIX <lancelot.six@amd.com>
|
|
Two tests make the claim that the DWARF assembler requires gcc,
however, this isn't true. I think at one point, when the DWARF
assembler was first added, we did use some techniques that were not
portable (see the comments in lib/dwarf.exp on function_range for
details), however, I think most DWARF assembler tests will now work
fine with Clang.
The two tests that I modify in this commit both work fine with Clang,
at least, I've tested with Clang 9.0.1 and 15.0.2, and don't see any
problems, so I'm removing the early return logic that stops these
tests from running with Clang.
Reviewed-By: Lancelot SIX <lancelot.six@amd.com>
|
|
values.
Currently, a non-trivial return value from a function cannot currently be
reliably determined on PowerPC. This is due to the fact that the PowerPC
ABI uses register r3 to store the address of the buffer containing the
non-trivial return value when the function is called. The PowerPC ABI
does not guarantee the value in register r3 is not modified in the
function. Thus the value in r3 cannot be reliably used to obtain the
return addreses on exit from the function.
This patch adds a new gdbarch method to allow PowerPC to access the value
of r3 on entry to a function. On PowerPC, the new gdbarch method attempts
to use the DW_OP_entry_value for the DWARF entries, when exiting the
function, to determine the value of r3 on entry to the function. This
requires the use of the -fvar-tracking compiler option to compile the
user application thus generating the DW_OP_entry_value in the binary. The
DW_OP_entry_value entries in the binary file allows GDB to resolve the
DW_TAG_call_site entries. This new gdbarch method is used to get the
return buffer address, in the case of a function returning a nontrivial
data type, on exit from the function. The GDB function should_stop checks
to see if RETURN_BUF is non-zero. By default, RETURN_BUF will be set to
zero by the new gdbarch method call for all architectures except PowerPC.
The get_return_value function will be used to obtain the return value on
all other architectures as is currently being done if RETURN_BUF is zero.
On PowerPC, the new gdbarch method will return a nonzero address in
RETURN_BUF if the value can be determined. The value_at function uses the
return buffer address to get the return value.
This patch fixes five testcase failures in gdb.cp/non-trivial-retval.exp.
The correct function return values are now reported.
Note this patch is dependent on patch: "PowerPC, function
ppc64_sysv_abi_return_value add missing return value convention".
This patch has been tested on Power 10 and x86-64 with no regressions.
|
|
The test gdb.cp/call-method-register.exp assumes that the class will be
placed on a register. However, this keyword has been deprecated since
C++11, and Clang, for instance, does not feel the need to follow it.
Since this test is not usable without this working, this commit marks
this test as untested.
Approved-by: Tom Tromey <tom@tromey.com>
|