[Lldb-commits] [lldb] [lldb] Fix assert when `target frame-provider register` succeeds (PR #208232)
https://github.com/medismailben closed https://github.com/llvm/llvm-project/pull/208232 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix assert when `target frame-provider register` succeeds (PR #208232)
https://github.com/medismailben auto_merge_enabled https://github.com/llvm/llvm-project/pull/208232 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix assert when `target frame-provider register` succeeds (PR #208232)
https://github.com/medismailben updated
https://github.com/llvm/llvm-project/pull/208232
>From daf736a4ea57a030fd007c13e68cbf218521b983 Mon Sep 17 00:00:00 2001
From: Med Ismail Bennani
Date: Wed, 8 Jul 2026 08:10:08 -0700
Subject: [PATCH] [lldb] Fix assert when `target frame-provider register`
succeeds
CommandObjectTargetFrameProviderRegister::DoExecute never called
CommandReturnObject::SetStatus() on its success path. CommandObject.cpp
has a DoExecuteStatusCheck RAII guard that resets the result's status to
eReturnStatusInvalid before DoExecute runs, and asserts on exit that
DoExecute changed it. AppendMessage()/AppendMessageWithFormatv() don't
touch status (unlike AppendError()/SetError(), which call
SetStatus(eReturnStatusFailed)), so on the success path the status stayed
eReturnStatusInvalid, tripping the assert.
This went unnoticed because every existing scripted_frame_provider test
uses SBTarget::RegisterScriptedFrameProvider directly, bypassing the
`target frame-provider register` command entirely. Add a regression test
that exercises the command instead.
Signed-off-by: Med Ismail Bennani
---
lldb/source/Commands/CommandObjectTarget.cpp | 1 +
.../register_command_status/Makefile | 2 +
.../TestFrameProviderRegisterCommandStatus.py | 39 +++
.../register_command_status/frame_provider.py | 16
.../register_command_status/main.c| 7
5 files changed, 65 insertions(+)
create mode 100644
lldb/test/API/functionalities/scripted_frame_provider/register_command_status/Makefile
create mode 100644
lldb/test/API/functionalities/scripted_frame_provider/register_command_status/TestFrameProviderRegisterCommandStatus.py
create mode 100644
lldb/test/API/functionalities/scripted_frame_provider/register_command_status/frame_provider.py
create mode 100644
lldb/test/API/functionalities/scripted_frame_provider/register_command_status/main.c
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp
b/lldb/source/Commands/CommandObjectTarget.cpp
index 28065a47fd413..4ef3a6fe82115 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -6175,6 +6175,7 @@ class CommandObjectTargetFrameProviderRegister : public
CommandObjectParsed {
result.AppendMessageWithFormatv(
"successfully registered scripted frame provider '{0}' for target",
m_class_options.GetName().c_str());
+result.SetStatus(eReturnStatusSuccessFinishResult);
}
OptionGroupPythonClassWithDict m_class_options;
diff --git
a/lldb/test/API/functionalities/scripted_frame_provider/register_command_status/Makefile
b/lldb/test/API/functionalities/scripted_frame_provider/register_command_status/Makefile
new file mode 100644
index 0..c9319d6e6888a
--- /dev/null
+++
b/lldb/test/API/functionalities/scripted_frame_provider/register_command_status/Makefile
@@ -0,0 +1,2 @@
+C_SOURCES := main.c
+include Makefile.rules
diff --git
a/lldb/test/API/functionalities/scripted_frame_provider/register_command_status/TestFrameProviderRegisterCommandStatus.py
b/lldb/test/API/functionalities/scripted_frame_provider/register_command_status/TestFrameProviderRegisterCommandStatus.py
new file mode 100644
index 0..82c2d46ef40a2
--- /dev/null
+++
b/lldb/test/API/functionalities/scripted_frame_provider/register_command_status/TestFrameProviderRegisterCommandStatus.py
@@ -0,0 +1,39 @@
+"""
+Test that `target frame-provider register` succeeds without asserting.
+
+DoExecute never called CommandReturnObject::SetStatus() on its success
+path. AppendMessage()/AppendMessageWithFormatv() don't touch the status
+the way AppendError()/SetError() do, so it stayed eReturnStatusInvalid
+and tripped CommandObject.cpp's DoExecuteStatusCheck assert.
+
+Every other scripted_frame_provider test goes through
+SBTarget::RegisterScriptedFrameProvider directly instead of this
+command, which is how this slipped through.
+"""
+
+import os
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+
+
+class TestFrameProviderRegisterCommandStatus(TestBase):
+NO_DEBUG_INFO_TESTCASE = True
+
+def test_register_command_succeeds(self):
+"""
+`target frame-provider register` should complete successfully
+(and not assert) when given a valid scripted frame provider class.
+"""
+self.build()
+
+lldbutil.run_to_name_breakpoint(self, "frame3")
+
+provider_path = os.path.join(self.getSourceDir(), "frame_provider.py")
+self.runCmd("command script import " + provider_path)
+
+self.expect(
+"target frame-provider register -C frame_provider.MinimalProvider",
+substrs=["successfully registered scripted frame provider"],
+)
diff --git
a/lldb/test/API/functionalities/scripted_frame_provider/register_command_status/frame_provider.py
b/lldb/test/API/function
[Lldb-commits] [lldb] [lldb] Fix assert when `target frame-provider register` succeeds (PR #208232)
@@ -0,0 +1,41 @@ +""" +Test that `target frame-provider register` succeeds without asserting. + +CommandObjectTargetFrameProviderRegister::DoExecute never called +CommandReturnObject::SetStatus() on its success path. CommandObject.cpp +has a DoExecuteStatusCheck RAII guard that asserts DoExecute always sets a +status; since AppendMessage()/AppendMessageWithFormatv() don't touch +status (unlike AppendError()/SetError(), which do), the status stayed +eReturnStatusInvalid on success, tripping the assert. + +This regression went unnoticed because every other scripted_frame_provider +test calls SBTarget::RegisterScriptedFrameProvider directly, bypassing +this command entirely. +""" + +import os +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * + + +class TestFrameProviderRegisterCommandStatus(TestBase): medismailben wrote: I've been matching the filename for the test class name for too long, so calling this TestCase feels weird to me. I'll stick with this. https://github.com/llvm/llvm-project/pull/208232 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix assert when `target frame-provider register` succeeds (PR #208232)
https://github.com/medismailben edited https://github.com/llvm/llvm-project/pull/208232 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix assert when `target frame-provider register` succeeds (PR #208232)
@@ -0,0 +1,3 @@ +C_SOURCES := main.c +CFLAGS_EXTRAS := -std=c99 Teemperor wrote: (I don't think c99 is needed) https://github.com/llvm/llvm-project/pull/208232 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix assert when `target frame-provider register` succeeds (PR #208232)
@@ -0,0 +1,41 @@ +""" +Test that `target frame-provider register` succeeds without asserting. + +CommandObjectTargetFrameProviderRegister::DoExecute never called Teemperor wrote: Claudish https://github.com/llvm/llvm-project/pull/208232 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix assert when `target frame-provider register` succeeds (PR #208232)
@@ -0,0 +1,41 @@ +""" +Test that `target frame-provider register` succeeds without asserting. + +CommandObjectTargetFrameProviderRegister::DoExecute never called +CommandReturnObject::SetStatus() on its success path. CommandObject.cpp +has a DoExecuteStatusCheck RAII guard that asserts DoExecute always sets a +status; since AppendMessage()/AppendMessageWithFormatv() don't touch +status (unlike AppendError()/SetError(), which do), the status stayed +eReturnStatusInvalid on success, tripping the assert. + +This regression went unnoticed because every other scripted_frame_provider +test calls SBTarget::RegisterScriptedFrameProvider directly, bypassing +this command entirely. +""" + +import os +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * + + +class TestFrameProviderRegisterCommandStatus(TestBase): Teemperor wrote: `TestCase` is also good. https://github.com/llvm/llvm-project/pull/208232 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix assert when `target frame-provider register` succeeds (PR #208232)
https://github.com/Teemperor approved this pull request. LGTR modulo comments https://github.com/llvm/llvm-project/pull/208232 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix assert when `target frame-provider register` succeeds (PR #208232)
https://github.com/Teemperor edited https://github.com/llvm/llvm-project/pull/208232 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix assert when `target frame-provider register` succeeds (PR #208232)
@@ -0,0 +1,3 @@ +C_SOURCES := main.c +CFLAGS_EXTRAS := -std=c99 Teemperor wrote: huh? https://github.com/llvm/llvm-project/pull/208232 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix assert when `target frame-provider register` succeeds (PR #208232)
llvmorg-github-actions[bot] wrote:
@llvm/pr-subscribers-lldb
Author: Med Ismail Bennani (medismailben)
Changes
`CommandObjectTargetFrameProviderRegister::DoExecute` never called
`CommandReturnObject::SetStatus()` on its success path. `CommandObject.cpp` has
a `DoExecuteStatusCheck` RAII guard that resets the result's status to
`eReturnStatusInvalid` before `DoExecute` runs, and asserts on exit that
`DoExecute` changed it. `AppendMessage()`/`AppendMessageWithFormatv()` don't
touch status (unlike AppendError()/SetError(), which call
`SetStatus(eReturnStatusFailed)`), so on the success path the status stayed
eReturnStatusInvalid, tripping the assert.
This went unnoticed because every existing `scripted_frame_provider` test uses
`SBTarget::RegisterScriptedFrameProvider` directly, bypassing the `target
frame-provider register` command entirely. Add a regression test that exercises
the command instead.
---
Full diff: https://github.com/llvm/llvm-project/pull/208232.diff
5 Files Affected:
- (modified) lldb/source/Commands/CommandObjectTarget.cpp (+1)
- (added)
lldb/test/API/functionalities/scripted_frame_provider/register_command_status/Makefile
(+3)
- (added)
lldb/test/API/functionalities/scripted_frame_provider/register_command_status/TestFrameProviderRegisterCommandStatus.py
(+41)
- (added)
lldb/test/API/functionalities/scripted_frame_provider/register_command_status/frame_provider.py
(+16)
- (added)
lldb/test/API/functionalities/scripted_frame_provider/register_command_status/main.c
(+7)
``diff
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp
b/lldb/source/Commands/CommandObjectTarget.cpp
index 28065a47fd413..4ef3a6fe82115 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -6175,6 +6175,7 @@ class CommandObjectTargetFrameProviderRegister : public
CommandObjectParsed {
result.AppendMessageWithFormatv(
"successfully registered scripted frame provider '{0}' for target",
m_class_options.GetName().c_str());
+result.SetStatus(eReturnStatusSuccessFinishResult);
}
OptionGroupPythonClassWithDict m_class_options;
diff --git
a/lldb/test/API/functionalities/scripted_frame_provider/register_command_status/Makefile
b/lldb/test/API/functionalities/scripted_frame_provider/register_command_status/Makefile
new file mode 100644
index 0..0b710c6e298ae
--- /dev/null
+++
b/lldb/test/API/functionalities/scripted_frame_provider/register_command_status/Makefile
@@ -0,0 +1,3 @@
+C_SOURCES := main.c
+CFLAGS_EXTRAS := -std=c99
+include Makefile.rules
diff --git
a/lldb/test/API/functionalities/scripted_frame_provider/register_command_status/TestFrameProviderRegisterCommandStatus.py
b/lldb/test/API/functionalities/scripted_frame_provider/register_command_status/TestFrameProviderRegisterCommandStatus.py
new file mode 100644
index 0..06287cadcf182
--- /dev/null
+++
b/lldb/test/API/functionalities/scripted_frame_provider/register_command_status/TestFrameProviderRegisterCommandStatus.py
@@ -0,0 +1,41 @@
+"""
+Test that `target frame-provider register` succeeds without asserting.
+
+CommandObjectTargetFrameProviderRegister::DoExecute never called
+CommandReturnObject::SetStatus() on its success path. CommandObject.cpp
+has a DoExecuteStatusCheck RAII guard that asserts DoExecute always sets a
+status; since AppendMessage()/AppendMessageWithFormatv() don't touch
+status (unlike AppendError()/SetError(), which do), the status stayed
+eReturnStatusInvalid on success, tripping the assert.
+
+This regression went unnoticed because every other scripted_frame_provider
+test calls SBTarget::RegisterScriptedFrameProvider directly, bypassing
+this command entirely.
+"""
+
+import os
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+
+
+class TestFrameProviderRegisterCommandStatus(TestBase):
+NO_DEBUG_INFO_TESTCASE = True
+
+def test_register_command_succeeds(self):
+"""
+`target frame-provider register` should complete successfully
+(and not assert) when given a valid scripted frame provider class.
+"""
+self.build()
+
+lldbutil.run_to_name_breakpoint(self, "frame3")
+
+provider_path = os.path.join(self.getSourceDir(), "frame_provider.py")
+self.runCmd("command script import " + provider_path)
+
+self.expect(
+"target frame-provider register -C frame_provider.MinimalProvider",
+substrs=["successfully registered scripted frame provider"],
+)
diff --git
a/lldb/test/API/functionalities/scripted_frame_provider/register_command_status/frame_provider.py
b/lldb/test/API/functionalities/scripted_frame_provider/register_command_status/frame_provider.py
new file mode 100644
index 0..b66060bc8a77f
--- /dev/null
+++
b/lldb/test/API/functionalities/scripted_frame_provider
[Lldb-commits] [lldb] [lldb] Fix assert when `target frame-provider register` succeeds (PR #208232)
https://github.com/medismailben created
https://github.com/llvm/llvm-project/pull/208232
`CommandObjectTargetFrameProviderRegister::DoExecute` never called
`CommandReturnObject::SetStatus()` on its success path. `CommandObject.cpp` has
a `DoExecuteStatusCheck` RAII guard that resets the result's status to
`eReturnStatusInvalid` before `DoExecute` runs, and asserts on exit that
`DoExecute` changed it. `AppendMessage()`/`AppendMessageWithFormatv()` don't
touch status (unlike AppendError()/SetError(), which call
`SetStatus(eReturnStatusFailed)`), so on the success path the status stayed
eReturnStatusInvalid, tripping the assert.
This went unnoticed because every existing `scripted_frame_provider` test uses
`SBTarget::RegisterScriptedFrameProvider` directly, bypassing the `target
frame-provider register` command entirely. Add a regression test that exercises
the command instead.
>From 9808fd70ab893fb1cbe32c58325095ecc5674a87 Mon Sep 17 00:00:00 2001
From: Med Ismail Bennani
Date: Wed, 8 Jul 2026 06:51:48 -0700
Subject: [PATCH] [lldb] Fix assert when `target frame-provider register`
succeeds
CommandObjectTargetFrameProviderRegister::DoExecute never called
CommandReturnObject::SetStatus() on its success path. CommandObject.cpp
has a DoExecuteStatusCheck RAII guard that resets the result's status to
eReturnStatusInvalid before DoExecute runs, and asserts on exit that
DoExecute changed it. AppendMessage()/AppendMessageWithFormatv() don't
touch status (unlike AppendError()/SetError(), which call
SetStatus(eReturnStatusFailed)), so on the success path the status stayed
eReturnStatusInvalid, tripping the assert.
This went unnoticed because every existing scripted_frame_provider test
uses SBTarget::RegisterScriptedFrameProvider directly, bypassing the
`target frame-provider register` command entirely. Add a regression test
that exercises the command instead.
---
lldb/source/Commands/CommandObjectTarget.cpp | 1 +
.../register_command_status/Makefile | 3 ++
.../TestFrameProviderRegisterCommandStatus.py | 41 +++
.../register_command_status/frame_provider.py | 16
.../register_command_status/main.c| 7
5 files changed, 68 insertions(+)
create mode 100644
lldb/test/API/functionalities/scripted_frame_provider/register_command_status/Makefile
create mode 100644
lldb/test/API/functionalities/scripted_frame_provider/register_command_status/TestFrameProviderRegisterCommandStatus.py
create mode 100644
lldb/test/API/functionalities/scripted_frame_provider/register_command_status/frame_provider.py
create mode 100644
lldb/test/API/functionalities/scripted_frame_provider/register_command_status/main.c
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp
b/lldb/source/Commands/CommandObjectTarget.cpp
index 28065a47fd413..4ef3a6fe82115 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -6175,6 +6175,7 @@ class CommandObjectTargetFrameProviderRegister : public
CommandObjectParsed {
result.AppendMessageWithFormatv(
"successfully registered scripted frame provider '{0}' for target",
m_class_options.GetName().c_str());
+result.SetStatus(eReturnStatusSuccessFinishResult);
}
OptionGroupPythonClassWithDict m_class_options;
diff --git
a/lldb/test/API/functionalities/scripted_frame_provider/register_command_status/Makefile
b/lldb/test/API/functionalities/scripted_frame_provider/register_command_status/Makefile
new file mode 100644
index 0..0b710c6e298ae
--- /dev/null
+++
b/lldb/test/API/functionalities/scripted_frame_provider/register_command_status/Makefile
@@ -0,0 +1,3 @@
+C_SOURCES := main.c
+CFLAGS_EXTRAS := -std=c99
+include Makefile.rules
diff --git
a/lldb/test/API/functionalities/scripted_frame_provider/register_command_status/TestFrameProviderRegisterCommandStatus.py
b/lldb/test/API/functionalities/scripted_frame_provider/register_command_status/TestFrameProviderRegisterCommandStatus.py
new file mode 100644
index 0..06287cadcf182
--- /dev/null
+++
b/lldb/test/API/functionalities/scripted_frame_provider/register_command_status/TestFrameProviderRegisterCommandStatus.py
@@ -0,0 +1,41 @@
+"""
+Test that `target frame-provider register` succeeds without asserting.
+
+CommandObjectTargetFrameProviderRegister::DoExecute never called
+CommandReturnObject::SetStatus() on its success path. CommandObject.cpp
+has a DoExecuteStatusCheck RAII guard that asserts DoExecute always sets a
+status; since AppendMessage()/AppendMessageWithFormatv() don't touch
+status (unlike AppendError()/SetError(), which do), the status stayed
+eReturnStatusInvalid on success, tripping the assert.
+
+This regression went unnoticed because every other scripted_frame_provider
+test calls SBTarget::RegisterScriptedFrameProvider directly, bypassing
+this command entirely.
+"""
+
+import os
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lld
