clayborg created this revision. clayborg added reviewers: labath, jingham, yinghuitan. Herald added a project: All. clayborg requested review of this revision. Herald added a project: LLDB. Herald added a subscriber: lldb-commits.
Before this fix if you tried to call fork for vfork, the expression would stop when it received the eStopReasonFork or eStopReasonVFork in the thread plan that runs the expression. This is now fixed and I have added a test case. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D129521 Files: lldb/source/Target/ThreadPlanCallFunction.cpp lldb/test/API/commands/expression/fork/Makefile lldb/test/API/commands/expression/fork/TestForkExprs.py lldb/test/API/commands/expression/fork/main.cpp
Index: lldb/test/API/commands/expression/fork/main.cpp =================================================================== --- /dev/null +++ lldb/test/API/commands/expression/fork/main.cpp @@ -0,0 +1,29 @@ +#include <sys/types.h> +#include <unistd.h> + +pid_t do_fork(char *const argv[], char *const envp[]) { + pid_t pid = fork(); + if (pid == 0) + execve(argv[0], argv, envp); + return pid; +} + +pid_t do_vfork(char *const argv[], char *const envp[]) { + pid_t pid = vfork(); + if (pid == 0) + execve(argv[0], argv, envp); + return pid; +} + +int main(int argc, char *const argv[], char *const envp[]) { + // Stop here to evaluate expressions + // Optionally call do_fork() when argc is 4 to make sure do_fork() doesn't get + // dead stripped + if (argc == 4) + do_fork(argv, envp); + // Optionally call do_vfork() when argc is 5 to make sure do_fork() doesn't + // get dead stripped + if (argc == 5) + do_vfork(argv, envp); + return 0; +} Index: lldb/test/API/commands/expression/fork/TestForkExprs.py =================================================================== --- /dev/null +++ lldb/test/API/commands/expression/fork/TestForkExprs.py @@ -0,0 +1,41 @@ +""" +Test some more expression commands. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ExprCommandsForkExpressions(TestBase): + + NO_DEBUG_INFO_TESTCASE = True + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + + @skipUnlessPlatform(["linux"]) + def test_more_expr_commands(self): + """Test some more expression commands.""" + self.build() + + (target, process, self.thread, bkpt) = lldbutil.run_to_source_breakpoint(self, + 'Stop here to evaluate expressions', + lldb.SBFileSpec("main.cpp")) + + self.assertTrue(bkpt.IsValid()) + bkpt.SetEnabled(False) + options = lldb.SBExpressionOptions() + options.SetIgnoreBreakpoints(True) + frame = self.thread.GetFrameAtIndex(0) + + value = frame.EvaluateExpression("do_fork(argv, envp)", options) + self.assertTrue(value.IsValid()) + self.assertSuccess(value.GetError()) + value = frame.EvaluateExpression("do_vfork(argv, envp)", options) + self.assertTrue(value.IsValid()) + self.assertSuccess(value.GetError()) Index: lldb/test/API/commands/expression/fork/Makefile =================================================================== --- /dev/null +++ lldb/test/API/commands/expression/fork/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules Index: lldb/source/Target/ThreadPlanCallFunction.cpp =================================================================== --- lldb/source/Target/ThreadPlanCallFunction.cpp +++ lldb/source/Target/ThreadPlanCallFunction.cpp @@ -267,6 +267,12 @@ if (stop_reason == eStopReasonBreakpoint && BreakpointsExplainStop()) return true; + if (stop_reason == eStopReasonFork || stop_reason == eStopReasonVFork || + stop_reason == eStopReasonVForkDone) { + LLDB_LOGF(log, "ThreadPlanCallFunction::PlanExplainsStop not done for fork stop reasons."); + return false; + } + // One more quirk here. If this event was from Halt interrupting the target, // then we should not consider ourselves complete. Return true to // acknowledge the stop. @@ -371,7 +377,7 @@ #ifndef SINGLE_STEP_EXPRESSIONS Thread &thread = GetThread(); - m_subplan_sp = std::make_shared<ThreadPlanRunToAddress>(thread, m_start_addr, + m_subplan_sp = std::make_shared<ThreadPlanRunToAddress>(thread, m_start_addr, m_stop_other_threads); thread.QueueThreadPlan(m_subplan_sp, false);
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits