mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-23 18:14:13 +08:00
gdb: reject inserting breakpoints between functions
When debugging ROCm code, you might have something like this: __global__ void kernel () { ... // break here ... } int main () { // Code to call `kernel` } ... where kernel is a function compiled to execute on the GPU. It does not exist in the host x86-64 program that runs the main function, and GDB doesn't know about that function until it is called, at which point the runtime loads the corresponding code object and GDB learns about the code of the "kernel" function. Before the GPU code object is loaded, from the point of view of GDB, you might as well have blank lines instead of the "kernel" function. The DWARF in the host program doesn't describe anything at these lines. So, a common problem that users face is: - Start GDB with the host binary - Place a breakpoint by line number at the "break here" line - At this point, GDB only knows about the host code, the lines of the `kernel` function are a big void. - GDB finds no code mapped to the "break here" line and searches for the first following line that has code mapped to it. - GDB finds that the line with the opening bracket of the `main` function (or around there) has code mapped to it, places breakpoint there. - User runs the program. - The programs hits the breakpoint at the start of main. - User is confused, because they didn't ask for a breakpoint in main. If they continue, the code object eventually gets loaded, GDB reads the debug info from it, re-evaluates the breakpoint locations, and at this point the breakpoint is placed at the expected location. The goal of this patch is to get rid of this annoyance. A case similar to the one shown above can actually be simulated without GPU-specific code: using a single source file to generate a library and an executable loading that library (see the new test gdb.linespec/line-breakpoint-outside-function.c for an example). Before the library is loaded, trying to place a breakpoint in the library code results in the breakpoint "drifting" down to the main function. To address this problem, make it so that when a user requests a breakpoint outside a function, GDB makes a pending breakpoint, rather than placing a breakpoint at the next line with code, which happens to be in the next function. When the GPU kernel or shared library gets loaded, the breakpoint resolves to a location in the kernel or library. Note that we still want breakpoints placed inside a function to "drift" down to the next line with code. For example, here: 9 10 void foo() 11 { 12 int x; 13 14 x++; There is probably no code associated to lines 10, 12 and 13, but the user can still reasonably expect to be able to put a breakpoint there. In my experience, GCC maps the function prologue to the line with the opening curly bracket, so the user will be able to place a breakpoint there anyway (line 11 in the example). But I don't really see a use case to put a breakpoint above line 10 and expect to get a breakpoint in foo. So I think that is a reasonable behavior change for GDB. This is implemented using the following heuristic: - If a breakpoint is requested at line L but there is no code mapped to L, search for a following line with associated code (this already exists today). - However, if: 1. the found location falls in a function symbol's block 2. the found location's address is equal the entry PC of that function 3. the found location's line is greater that the requested line ... then we don't place a breakpoint at the found location, we will end up with a pending breakpoint. Change the message "No line X in file..." to "No compiled code for line X in file...". There is clearly a line 9 in the example above, so it would be weird to say "No line 9 in file...". What we mean is that there is no code associated to line 9. All the regressions that I found this patch to cause were: 1. tests specifically this behavior where placing a breakpoint before a function results in a breakpoint on that function, in which case I removed the tests or changed them to expect a pending breakpoint 2. linespec tests expecting things like "break -line N garbage" to error out because of the following garbage, but we now got a different error because line N now doesn't resolve to something anymore. For example, before: (gdb) break -line 3 if foofoofoo == 1 No symbol "foofoofoo" in current context. became (gdb) break -line 3 if foofoofoo == 1 No line 3 in the current file. These tests were modified to refer to a valid line with code, so that we can still test what we intended to test. Notes: - The CUDA compiler "solves" this problem by adding dummy function symbols between functions, that are never called. So when you try to insert a breakpoint in the not-yet-loaded kernel, the breakpoint still drifts, but is placed on some dummy symbol. For reasons that would be too long to explain here, the ROCm compiler does not do that, and it is not a desirable option. - You can have constructs like this: void host_function() { struct foo { static void __global__ kernel () { // Place breakpoint here } }; // Host code that calls `kernel` } The heuristic won't work then, as the breakpoint will drift somewhere inside the enclosing function, but won't be at the start of that function. So a bogus breakpoint location will be created on the host side. I don't think that people are going to use this kind of construct often though, so we can probably ignore it (or at least it shouldn't prevent making the more common case better). ROCm doesn't support passing a lambda kernel function to hipLaunchKernelGGL (the function used to launch kernels on the device), but if it eventually does, there will be the same problem. I think that to properly support this, we will need some DWARF improvements to be able to say "there is really nothing at these lines" in the line table. Co-Authored-By: Simon Marchi <simon.marchi@efficios.com> Change-Id: I3cc12cfa823dc7d8e24dd4d35bced8e8baf7f9b6
This commit is contained in:
parent
83fbcee1a1
commit
dcaa85e58c
@ -2067,12 +2067,19 @@ create_sals_line_offset (struct linespec_state *self,
|
||||
const linetable_entry *best_entry = NULL;
|
||||
int i, j;
|
||||
|
||||
/* True if the provided line gave an exact match. False if we had to
|
||||
search for the next following line with code. */
|
||||
bool was_exact = true;
|
||||
|
||||
std::vector<symtab_and_line> intermediate_results
|
||||
= decode_digits_ordinary (self, ls, val.line, &best_entry);
|
||||
if (intermediate_results.empty () && best_entry != NULL)
|
||||
intermediate_results = decode_digits_ordinary (self, ls,
|
||||
best_entry->line,
|
||||
&best_entry);
|
||||
{
|
||||
was_exact = false;
|
||||
intermediate_results = decode_digits_ordinary (self, ls,
|
||||
best_entry->line,
|
||||
&best_entry);
|
||||
}
|
||||
|
||||
/* For optimized code, the compiler can scatter one source line
|
||||
across disjoint ranges of PC values, even when no duplicate
|
||||
@ -2115,11 +2122,45 @@ create_sals_line_offset (struct linespec_state *self,
|
||||
struct symbol *sym = (blocks[i]
|
||||
? blocks[i]->containing_function ()
|
||||
: NULL);
|
||||
symtab_and_line &sal = intermediate_results[i];
|
||||
|
||||
/* Don't consider a match if:
|
||||
|
||||
- the provided line did not give an exact match (so we
|
||||
started looking for lines below until we found one with
|
||||
code associated to it)
|
||||
- the found location is exactly the start of a function
|
||||
- the provided line is above the declaration line of the
|
||||
function
|
||||
|
||||
Consider the following source:
|
||||
|
||||
10 } // end of a previous function
|
||||
11
|
||||
12 int
|
||||
13 main (void)
|
||||
14 {
|
||||
15 int i = 1;
|
||||
16
|
||||
17 return 0;
|
||||
18 }
|
||||
|
||||
The intent of this heuristic is that a breakpoint requested on
|
||||
line 11 and 12 will not result in a breakpoint on main, but a
|
||||
breakpoint on line 13 will. A breakpoint requested on the empty
|
||||
line 16 will also result in a breakpoint in main, at line 17. */
|
||||
if (!was_exact
|
||||
&& sym != nullptr
|
||||
&& sym->aclass () == LOC_BLOCK
|
||||
&& sal.pc == sym->value_block ()->entry_pc ()
|
||||
&& val.line < sym->line ())
|
||||
continue;
|
||||
|
||||
if (self->funfirstline)
|
||||
skip_prologue_sal (&intermediate_results[i]);
|
||||
intermediate_results[i].symbol = sym;
|
||||
add_sal_to_sals (self, &values, &intermediate_results[i],
|
||||
skip_prologue_sal (&sal);
|
||||
|
||||
sal.symbol = sym;
|
||||
add_sal_to_sals (self, &values, &sal,
|
||||
sym ? sym->natural_name () : NULL, 0);
|
||||
}
|
||||
}
|
||||
@ -2127,10 +2168,12 @@ create_sals_line_offset (struct linespec_state *self,
|
||||
if (values.empty ())
|
||||
{
|
||||
if (ls->explicit_loc.source_filename)
|
||||
throw_error (NOT_FOUND_ERROR, _("No line %d in file \"%s\"."),
|
||||
throw_error (NOT_FOUND_ERROR,
|
||||
_("No compiled code for line %d in file \"%s\"."),
|
||||
val.line, ls->explicit_loc.source_filename.get ());
|
||||
else
|
||||
throw_error (NOT_FOUND_ERROR, _("No line %d in the current file."),
|
||||
throw_error (NOT_FOUND_ERROR,
|
||||
_("No compiled code for line %d in the current file."),
|
||||
val.line);
|
||||
}
|
||||
|
||||
|
@ -40,10 +40,13 @@ proc set_breakpoint_on_gcd_function {} {
|
||||
# Single hex digit
|
||||
set xd {[0-9a-f]}
|
||||
|
||||
# This accepts e.g. "Breakpoint 1 at 0x40968a" (fixed GDB)
|
||||
# but rejects e.g. "Breakpoint 1 at 0x4" (broken GDB).
|
||||
gdb_test "b [gdb_get_line_number "gdb break here"]" \
|
||||
"Breakpoint \[0-9\] at 0x${xd}${xd}+: .*"
|
||||
set lineno [gdb_get_line_number "gdb break here"]
|
||||
gdb_test "set breakpoint pending on"
|
||||
gdb_test "b $lineno" \
|
||||
[multi_line \
|
||||
"^No compiled code for line $lineno in the current file\\." \
|
||||
"Breakpoint $::decimal \\($lineno\\) pending\\."] \
|
||||
"break on line in garbage collected function"
|
||||
}
|
||||
|
||||
set_breakpoint_on_gcd_function
|
||||
|
@ -476,9 +476,6 @@ proc_with_prefix test_no_break_on_catchpoint {} {
|
||||
|
||||
test_no_break_on_catchpoint
|
||||
|
||||
# Verify that GDB responds gracefully when asked to set a breakpoint
|
||||
# on a nonexistent source line.
|
||||
|
||||
proc_with_prefix test_break_nonexistent_line {} {
|
||||
clean_restart break
|
||||
|
||||
@ -486,9 +483,11 @@ proc_with_prefix test_break_nonexistent_line {} {
|
||||
return
|
||||
}
|
||||
|
||||
# Verify that GDB responds gracefully when asked to set a
|
||||
# breakpoint on a nonexistent source line.
|
||||
gdb_test_no_output "set breakpoint pending off"
|
||||
gdb_test "break 999" \
|
||||
"No line 999 in the current file." \
|
||||
"^No compiled code for line 999 in the current file\\." \
|
||||
"break on non-existent source line"
|
||||
}
|
||||
|
||||
|
@ -32,24 +32,15 @@ if { [prepare_for_testing "failed to prepare" $testfile $srcfile $flags] } {
|
||||
}
|
||||
remote_exec build "rm -f core"
|
||||
|
||||
# CHFts23469: Test that you can "clear" a bp set at
|
||||
# a line _before_ the routine (which will default to the
|
||||
# first line in the routine, which turns out to correspond
|
||||
# to the prolog--that's another bug...)
|
||||
#
|
||||
|
||||
gdb_test "b ending-run.c:1" ".*Breakpoint.*ending-run.c, line 1.*" \
|
||||
"bpt at line before routine"
|
||||
|
||||
set break1_line [gdb_get_line_number "-break1-"]
|
||||
gdb_test "b ending-run.c:$break1_line" \
|
||||
".*Note.*also.*Breakpoint 2.*ending-run.c, line $break1_line.*" \
|
||||
"Breakpoint 1 at ${::hex}.*" \
|
||||
"b ending-run.c:$break1_line, one"
|
||||
|
||||
# Set up to go to the next-to-last line of the program
|
||||
#
|
||||
set break2_line [gdb_get_line_number "-break2-"]
|
||||
gdb_test "b ending-run.c:$break2_line" ".*Breakpoint 3.*ending-run.c, line $break2_line.*"
|
||||
gdb_test "b ending-run.c:$break2_line" ".*Breakpoint 2.*ending-run.c, line $break2_line.*"
|
||||
|
||||
# Expect to hit the bp at line "1", but symbolize this
|
||||
# as line "13". Then try to clear it--this should work.
|
||||
@ -57,29 +48,28 @@ gdb_test "b ending-run.c:$break2_line" ".*Breakpoint 3.*ending-run.c, line $brea
|
||||
gdb_run_cmd
|
||||
gdb_test "" ".*Breakpoint.*1.*callee.*$break1_line.*" "run"
|
||||
|
||||
gdb_test "cle" ".*Deleted breakpoints 1 2.*" "clear worked"
|
||||
gdb_test_multiple "i b" "cleared bp at line before routine" {
|
||||
-re ".* breakpoint .* breakpoint .*$gdb_prompt $" {
|
||||
fail "cleared bp at line before routine"
|
||||
gdb_test "cle" "Deleted breakpoint 1 " "clear worked"
|
||||
gdb_test_multiple "i b" "cleared bp at stopped line" {
|
||||
-re ".* breakpoint .* breakpoint .*$gdb_prompt $" {
|
||||
fail $gdb_test_name
|
||||
}
|
||||
-re ".*3.*main.*$break2_line.*$gdb_prompt $" {
|
||||
pass "cleared bp at line before routine"
|
||||
-re ".*2.*main.*$break2_line.*$gdb_prompt $" {
|
||||
pass $gdb_test_name
|
||||
}
|
||||
}
|
||||
|
||||
# Test some other "clear" combinations
|
||||
#
|
||||
gdb_test "b ending-run.c:1" ".*Breakpoint.*4.*"
|
||||
gdb_test "b ending-run.c:$break1_line" ".*Note.*also.*Breakpoint.*5.*" "b ending-run.c:$break1_line, two"
|
||||
gdb_test "b ending-run.c:$break1_line" "Breakpoint 3 at ${::hex}.*" "b ending-run.c:$break1_line, two"
|
||||
gdb_test "cle ending-run.c:$break1_line" \
|
||||
".*Deleted breakpoints 4 5.*" "Cleared 2 by line"
|
||||
"Deleted breakpoint 3 " "Cleared 2 by line"
|
||||
|
||||
gdb_test_multiple "info line ending-run.c:$break1_line" "" {
|
||||
-re ".*address (0x\[0-9a-fA-F]*).*$gdb_prompt $" {
|
||||
set line_nine $expect_out(1,string)
|
||||
gdb_test "b ending-run.c:$break1_line" ".*Breakpoint 6.*ending-run.c, line $break1_line.*"
|
||||
gdb_test "b *$line_nine" ".*Note.*also.*Breakpoint 7.*" "breakpoint 7 at *ending-run.c:$break1_line"
|
||||
gdb_test "cle" ".*Deleted breakpoints 6 7.*" "clear 2 by default"
|
||||
gdb_test "b ending-run.c:$break1_line" ".*Breakpoint 4.*ending-run.c, line $break1_line.*"
|
||||
gdb_test "b *$line_nine" ".*Note.*also.*Breakpoint 5.*" "breakpoint 7 at *ending-run.c:$break1_line"
|
||||
gdb_test "cle" "Deleted breakpoints 4 5 " "clear 2 by default"
|
||||
}
|
||||
-re ".*$gdb_prompt $" {
|
||||
fail "need to fix test for new compile outcome"
|
||||
@ -90,7 +80,7 @@ gdb_test_multiple "i b" "all set to continue" {
|
||||
-re ".* breakpoint .* breakpoint .*$gdb_prompt $" {
|
||||
fail "all set to continue (didn't clear bps)"
|
||||
}
|
||||
-re ".*3.*main.*$break2_line.*$gdb_prompt $" {
|
||||
-re ".*2.*main.*$break2_line.*$gdb_prompt $" {
|
||||
pass "all set to continue"
|
||||
}
|
||||
-re ".*$gdb_prompt $" {
|
||||
|
@ -127,7 +127,7 @@ proc do_follow_exec_mode_tests { mode cmd infswitch } {
|
||||
# past it.
|
||||
#
|
||||
if {$cmd == "continue"} {
|
||||
gdb_breakpoint "$execd_line"
|
||||
gdb_breakpoint "$execd_line" "allow-pending"
|
||||
}
|
||||
|
||||
# Execute past the exec call.
|
||||
|
@ -296,7 +296,7 @@ if {![runto_main]} {
|
||||
#
|
||||
gdb_test_no_output "set breakpoint pending off"
|
||||
gdb_test "hbreak 999" \
|
||||
"No line 999 in the current file." \
|
||||
"^No compiled code for line 999 in the current file\\." \
|
||||
"hardware break on non-existent source line"
|
||||
|
||||
# Run to the desired default location. If not positioned here, the
|
||||
|
@ -296,7 +296,7 @@ gdb_test "catch exec" "Catchpoint \[0-9\]+ \\(exec\\)" \
|
||||
#
|
||||
|
||||
gdb_test_no_output "set breakpoint pending off"
|
||||
gdb_test "break 999" "No line 999 in the current file." \
|
||||
gdb_test "break 999" "^No compiled code for line 999 in the current file\\." \
|
||||
"break on non-existent source line"
|
||||
|
||||
# Run to the desired default location. If not positioned here, the
|
||||
|
@ -80,7 +80,7 @@ namespace eval $testfile {
|
||||
add linespecs "-function myclass::myfunction -line 3" $location(normal)
|
||||
add linespecs "-function myclass::myfunction -label top -line 3" \
|
||||
$location(top)
|
||||
add linespecs "-line 3" $location(normal)
|
||||
add linespecs "-line 25" $location(normal)
|
||||
add linespecs "-function myclass::operator," $location(operator)
|
||||
add linespecs "-function 'myclass::operator,'" $location(operator)
|
||||
add linespecs "-function \"myclass::operator,\"" $location(operator)
|
||||
|
@ -86,7 +86,7 @@ namespace eval $testfile {
|
||||
# These are also not yet supported; -line is silently ignored.
|
||||
add linespecs "-function myfunction -line 3" $location(normal)
|
||||
add linespecs "-function myfunction -label top -line 3" $location(top)
|
||||
add linespecs "-line 3" $location(normal)
|
||||
add linespecs "-line 25" $location(normal)
|
||||
|
||||
# Fire up gdb.
|
||||
if {![runto_main]} {
|
||||
|
@ -0,0 +1,51 @@
|
||||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2022-2024 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* The section where THE_LIB_PATH is not defined is compiled as a shared
|
||||
library. The rest is compiled as the main executable (which loads the
|
||||
shared library. */
|
||||
|
||||
#if !defined(THE_LIB_PATH)
|
||||
|
||||
void
|
||||
the_lib_func (void)
|
||||
{
|
||||
static int x;
|
||||
/* break here */
|
||||
x++;
|
||||
}
|
||||
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
void *lib = dlopen (THE_LIB_PATH, RTLD_NOW);
|
||||
assert (lib != NULL);
|
||||
|
||||
void (*the_lib_func) (void) = dlsym (lib, "the_lib_func");
|
||||
assert (the_lib_func != NULL);
|
||||
|
||||
the_lib_func ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,55 @@
|
||||
# Copyright 2022-2024 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Test that placing a line breakpoint outside a function results in a pending
|
||||
# breakpoint. More importantly, that it does "drift" and place a
|
||||
# breakpoint on the next function.
|
||||
#
|
||||
# See the .c file for more details.
|
||||
|
||||
standard_testfile
|
||||
|
||||
set shlib_path [standard_output_file ${testfile}-lib.so]
|
||||
if {[build_executable "build shlib" $shlib_path $srcfile {debug shlib}]} {
|
||||
return
|
||||
}
|
||||
|
||||
set opts [list debug shlib_load additional_flags=-DTHE_LIB_PATH="${shlib_path}"]
|
||||
if {[build_executable "failed to prepare" ${testfile} ${srcfile} $opts]} {
|
||||
return
|
||||
}
|
||||
|
||||
proc do_test {} {
|
||||
clean_restart $::binfile
|
||||
|
||||
# To make things easier, just so we don't have to deal with the question.
|
||||
gdb_test_no_output "set breakpoint pending on"
|
||||
|
||||
set lineno [gdb_get_line_number "break here"]
|
||||
gdb_test "break $lineno" \
|
||||
[multi_line \
|
||||
"No compiled code for line $lineno in the current file\\." \
|
||||
"Breakpoint 1 \\($lineno\\) pending\\."] \
|
||||
"breakpoint on a line outside any function"
|
||||
|
||||
gdb_run_cmd
|
||||
gdb_test_multiple "" "stop on lib function breakpoint" {
|
||||
-re -wrap "Breakpoint 1, the_lib_func .*29.*x\\+\\+.*" {
|
||||
pass $gdb_test_name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
do_test
|
@ -21,6 +21,16 @@ myfunction (int aa)
|
||||
int i;
|
||||
|
||||
i = aa + 42;
|
||||
|
||||
/* These lines are intentionally left blank such that the tests trying
|
||||
to place breakpoints at line -10 relative to the "set.breakpoint.here"
|
||||
line below land on a valid breakpoint location, inside the function. */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return i; /* set breakpoint here */
|
||||
}
|
||||
|
||||
|
@ -71,8 +71,8 @@ proc do_test {lang} {
|
||||
"Undefined convenience variable or function \"%s\" not defined in \"%s\"."
|
||||
invalid_label "No label \"%s\" defined in function \"%s\"."
|
||||
invalid_parm "invalid linespec argument, \"%s\""
|
||||
invalid_offset "No line %d in the current file."
|
||||
invalid_offset_f "No line %d in file \"%s\"."
|
||||
invalid_offset "No compiled code for line %d in the current file."
|
||||
invalid_offset_f "No compiled code for line %d in file \"%s\"."
|
||||
malformed_line_offset "malformed line offset: \"%s\""
|
||||
source_incomplete \
|
||||
"Source filename requires function, label, or line offset."
|
||||
@ -135,14 +135,14 @@ proc do_test {lang} {
|
||||
|
||||
foreach x {1 +1 +100 -10} {
|
||||
test_break "3 $x" unexpected_opt "number" $x
|
||||
test_break "-line 3 $x" garbage $x
|
||||
test_break "-line 34 $x" garbage $x
|
||||
test_break "+10 $x" unexpected_opt "number" $x
|
||||
test_break "-line +10 $x" garbage $x
|
||||
test_break "-10 $x" unexpected_opt "number" $x
|
||||
test_break "-line -10 $x" garbage $x
|
||||
}
|
||||
|
||||
foreach x {3 +10 -10} {
|
||||
foreach x {34 +10 -10} {
|
||||
test_break "$x foo" unexpected_opt "string" "foo"
|
||||
test_break "-line $x foo" garbage "foo"
|
||||
}
|
||||
@ -207,12 +207,12 @@ proc do_test {lang} {
|
||||
|
||||
test_break "${srcfile}::" invalid_function "${srcfile}::"
|
||||
test_break "$srcfile:3 1" unexpected_opt "number" "1"
|
||||
test_break "-source $srcfile -line 3 1" garbage "1"
|
||||
test_break "-source $srcfile -line 34 1" garbage "1"
|
||||
test_break "$srcfile:3 +100" unexpected_opt "number" "+100"
|
||||
test_break "-source $srcfile -line 3 +100" garbage "+100"
|
||||
test_break "-source $srcfile -line 34 +100" garbage "+100"
|
||||
test_break "$srcfile:3 -100" unexpected_opt "number" "-100"
|
||||
test_break "$srcfile:3 foo" unexpected_opt "string" "foo"
|
||||
test_break "-source $srcfile -line 3 foo" garbage "foo"
|
||||
test_break "-source $srcfile -line 34 foo" garbage "foo"
|
||||
|
||||
foreach x $invalid_offsets {
|
||||
test_break "$srcfile:$x" invalid_offset_f $x $srcfile
|
||||
|
@ -743,7 +743,9 @@ proc_with_prefix test_bkpt_explicit_loc {} {
|
||||
"No source file named foo.*" \
|
||||
"set invalid explicit breakpoint by missing source and line"
|
||||
gdb_test "python bp1 = gdb.Breakpoint (source=\"$srcfile\", line=\"900\")" \
|
||||
"No line 900 in file \"$srcfile\".*" \
|
||||
[multi_line \
|
||||
"^No compiled code for line 900 in file \"$srcfile\"\\." \
|
||||
"Breakpoint $::decimal \[^\r\n\]+ pending\\."] \
|
||||
"set invalid explicit breakpoint by source and invalid line"
|
||||
gdb_test "python bp1 = gdb.Breakpoint (function=\"blah\")" \
|
||||
"Function \"blah\" not defined.*" \
|
||||
|
@ -342,10 +342,10 @@ gdb_test "disassemble gdb_c_test" \
|
||||
"8.36: trace disassembly"
|
||||
|
||||
gdb_test "tfind line 0" \
|
||||
"out of range.*|failed to find.*|No line 0 in .*" \
|
||||
"out of range.*|failed to find.*|No compiled code for line 0 in .*" \
|
||||
"8.18: tfind line 0"
|
||||
gdb_test "tfind line 32767" \
|
||||
"out of range.*|failed to find.*|No line 32767 in .*" \
|
||||
"out of range.*|failed to find.*|No compiled code for line 32767 in .*" \
|
||||
"8.27: tfind line 32767"
|
||||
gdb_test "tfind line NoSuChFiLe.c:$baseline" \
|
||||
"No source file named.*" \
|
||||
|
@ -64,7 +64,8 @@ gdb_test "info trace" "in gdb_recursion_test.*$srcfile:$testline2.
|
||||
# 1.2 trace invalid source line
|
||||
gdb_delete_tracepoints
|
||||
gdb_test_no_output "set breakpoint pending off"
|
||||
gdb_test "trace $srcfile:99999" "No line 99999 in file \".*$srcfile\"." \
|
||||
gdb_test "trace $srcfile:99999" \
|
||||
"No compiled code for line 99999 in file \".*$srcfile\"\\." \
|
||||
"1.2a: trace invalid line in sourcefile"
|
||||
gdb_test "info trace" "No tracepoints.*" \
|
||||
"1.2b: reject invalid line in srcfile"
|
||||
|
Loading…
Reference in New Issue
Block a user