[Support] [lldb] Fix thread jump #45326 (#135778)
Fixes #45326
When you thread jump by calling
`j +2` or `thread jump --by +2` the offset is not recognised. This
commit fixes that.
---------
Signed-off-by: Ebuka Ezike <yerimyah1@gmail.com>
diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp
index 224c523..57c23d5 100644
--- a/lldb/source/Commands/CommandObjectThread.cpp
+++ b/lldb/source/Commands/CommandObjectThread.cpp
@@ -1649,11 +1649,14 @@
return Status::FromErrorStringWithFormat("invalid line number: '%s'.",
option_arg.str().c_str());
break;
- case 'b':
+ case 'b': {
+ option_arg.consume_front("+");
+
if (option_arg.getAsInteger(0, m_line_offset))
return Status::FromErrorStringWithFormat("invalid line offset: '%s'.",
option_arg.str().c_str());
break;
+ }
case 'a':
m_load_addr = OptionArgParser::ToAddress(execution_context, option_arg,
LLDB_INVALID_ADDRESS, &error);
diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index eb2e511..8aa52c9 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -1136,7 +1136,8 @@
def thread_jump_line : Option<"line", "l">, Group<1>, Arg<"LineNum">,
Required, Desc<"Specifies the line number to jump to.">;
def thread_jump_by : Option<"by", "b">, Group<2>, Arg<"Offset">, Required,
- Desc<"Jumps by a relative line offset from the current line.">;
+ Desc<"Jumps by a relative line offset from the current line,"
+ "can be a positive or negative offset">;
def thread_jump_address : Option<"address", "a">, Group<3>,
Arg<"AddressOrExpression">, Required, Desc<"Jumps to a specific address.">;
def thread_jump_force : Option<"force", "r">, Groups<[1,2,3]>,
diff --git a/lldb/test/API/functionalities/thread/jump/TestThreadJump.py b/lldb/test/API/functionalities/thread/jump/TestThreadJump.py
index 3c13a96..d603580 100644
--- a/lldb/test/API/functionalities/thread/jump/TestThreadJump.py
+++ b/lldb/test/API/functionalities/thread/jump/TestThreadJump.py
@@ -10,9 +10,12 @@
class ThreadJumpTestCase(TestBase):
+ def setUp(self):
+ TestBase.setUp(self)
+ self.build()
+
def test(self):
"""Test thread jump handling."""
- self.build()
exe = self.getBuildArtifact("a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
@@ -62,6 +65,71 @@
substrs=["error"],
)
+ def test_jump_offset(self):
+ """Test Thread Jump by negative or positive offset"""
+ exe = self.getBuildArtifact("a.out")
+ file_name = "main.cpp"
+ self.runCmd(f"target create {exe}", CURRENT_EXECUTABLE_SET)
+
+ pos_jump = line_number(file_name, "// jump_offset 1")
+ neg_jump = line_number(file_name, "// jump_offset 2")
+ pos_breakpoint = line_number(file_name, "// breakpoint 1")
+ neg_breakpoint = line_number(file_name, "// breakpoint 2")
+ pos_jump_offset = pos_jump - pos_breakpoint
+ neg_jump_offset = neg_jump - neg_breakpoint
+
+ var_1, var_1_value = ("var_1", "10")
+ var_2, var_2_value = ("var_2", "40")
+ var_3, var_3_value = ("var_3", "10")
+
+ # create pos_breakpoint and neg_breakpoint
+ lldbutil.run_break_set_by_file_and_line(
+ self, file_name, pos_breakpoint, num_expected_locations=1
+ )
+ lldbutil.run_break_set_by_file_and_line(
+ self, file_name, neg_breakpoint, num_expected_locations=1
+ )
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # test positive jump
+ # The stop reason of the thread should be breakpoint 1.
+ self.expect(
+ "thread list",
+ STOPPED_DUE_TO_BREAKPOINT + " 1",
+ substrs=[
+ "stopped",
+ f"{file_name}:{pos_breakpoint}",
+ "stop reason = breakpoint 1",
+ ],
+ )
+
+ self.runCmd(f"thread jump --by +{pos_jump_offset}")
+ self.expect("process status", substrs=[f"at {file_name}:{pos_jump}"])
+ self.expect(f"print {var_1}", substrs=[var_1_value])
+
+ self.runCmd("thread step-over")
+ self.expect(f"print {var_2}", substrs=[var_2_value])
+
+ self.runCmd("continue")
+
+ # test negative jump
+ # The stop reason of the thread should be breakpoint 1.
+ self.expect(
+ "thread list",
+ STOPPED_DUE_TO_BREAKPOINT + " 2",
+ substrs=[
+ "stopped",
+ f"{file_name}:{neg_breakpoint}",
+ "stop reason = breakpoint 2",
+ ],
+ )
+
+ self.runCmd(f"thread jump --by {neg_jump_offset}")
+ self.expect("process status", substrs=[f"at {file_name}:{neg_jump}"])
+ self.runCmd("thread step-over")
+ self.expect(f"print {var_3}", substrs=[var_3_value])
+
def do_min_test(self, start, jump, var, value):
# jump to the start marker
self.runCmd("j %i" % start)
diff --git a/lldb/test/API/functionalities/thread/jump/main.cpp b/lldb/test/API/functionalities/thread/jump/main.cpp
index d3c0de2..9c7f0bc 100644
--- a/lldb/test/API/functionalities/thread/jump/main.cpp
+++ b/lldb/test/API/functionalities/thread/jump/main.cpp
@@ -13,6 +13,21 @@
}
}
+int jump_positive_offset() {
+ int var_1 = 10;
+ var_1 = 20; // breakpoint 1
+
+ int var_2 = 40; // jump_offset 1
+ return var_2;
+}
+
+int jump_negative_offset() {
+ int var_3 = 10; // jump_offset 2
+ var_3 = 99;
+
+ return var_3; // breakpoint 2
+}
+
int main ()
{
int i;
@@ -22,5 +37,7 @@
i = min(min_i_a, min_i_b); // 3rd marker
j = min(min_j_a, min_j_b); // 4th marker
+ jump_positive_offset();
+ jump_negative_offset();
return 0;
}