@@ -811,38 +811,25 @@ void GlobalDebuggerUI::SetupMenu(UIContext* context)
811811 requireBinaryView));
812812 debuggerMenu->addAction (" Toggle Breakpoint" , " Breakpoint" );
813813
814- // Helper function to check if there's an enabled breakpoint at the current address
815- auto hasEnabledBreakpoint = [](BinaryView* view, uint64_t addr) -> bool {
814+ // Helper function to check if there's a breakpoint at the current address and return its enabled state
815+ auto getBreakpointEnabledState = [](BinaryView* view, uint64_t addr) -> std::pair< bool , bool > {
816816 auto controller = DebuggerController::GetController (view);
817817 if (!controller)
818- return false ;
819-
820- std::vector<DebugBreakpoint> breakpoints = controller->GetBreakpoints ();
821- for (const auto & bp : breakpoints)
822- {
823- if (bp.address == addr)
824- return bp.enabled ;
825- }
826- return false ;
827- };
828-
829- // Helper function to check if there's a disabled breakpoint at the current address
830- auto hasDisabledBreakpoint = [](BinaryView* view, uint64_t addr) -> bool {
831- auto controller = DebuggerController::GetController (view);
832- if (!controller)
833- return false ;
818+ return {false , false }; // {hasBreakpoint, isEnabled}
834819
835820 std::vector<DebugBreakpoint> breakpoints = controller->GetBreakpoints ();
836821 for (const auto & bp : breakpoints)
837822 {
838823 if (bp.address == addr)
839- return ! bp.enabled ;
824+ return { true , bp.enabled } ;
840825 }
841- return false ;
826+ return { false , false } ;
842827 };
843828
844- // Register "Enable Breakpoint" action (shown when breakpoint is disabled)
829+ // Register dynamic "Enable/Disable Breakpoint" action
845830 UIAction::registerAction (" Enable Breakpoint" );
831+ UIAction::registerAction (" Disable Breakpoint" );
832+
846833 context->globalActions ()->bindAction (" Enable Breakpoint" ,
847834 UIAction (
848835 [=](const UIActionContext& ctxt) {
@@ -852,26 +839,32 @@ void GlobalDebuggerUI::SetupMenu(UIContext* context)
852839 if (!controller)
853840 return ;
854841
842+ auto [hasBreakpoint, isEnabled] = getBreakpointEnabledState (ctxt.binaryView , ctxt.address );
855843 bool isAbsoluteAddress = controller->IsConnected ();
844+
856845 if (isAbsoluteAddress)
857846 {
858- controller->EnableBreakpoint (ctxt.address );
847+ if (isEnabled)
848+ controller->DisableBreakpoint (ctxt.address );
849+ else
850+ controller->EnableBreakpoint (ctxt.address );
859851 }
860852 else
861853 {
862854 std::string filename = controller->GetInputFile ();
863855 uint64_t offset = ctxt.address - controller->GetViewFileSegmentsStart ();
864856 ModuleNameAndOffset info = {filename, offset};
865- controller->EnableBreakpoint (info);
857+ if (isEnabled)
858+ controller->DisableBreakpoint (info);
859+ else
860+ controller->EnableBreakpoint (info);
866861 }
867862 },
868863 [=](const UIActionContext& ctxt) {
869- return ctxt.binaryView && hasDisabledBreakpoint (ctxt.binaryView , ctxt.address );
864+ auto [hasBreakpoint, isEnabled] = getBreakpointEnabledState (ctxt.binaryView , ctxt.address );
865+ return ctxt.binaryView && hasBreakpoint && !isEnabled;
870866 }));
871- debuggerMenu->addAction (" Enable Breakpoint" , " Breakpoint" );
872-
873- // Register "Disable Breakpoint" action (shown when breakpoint is enabled)
874- UIAction::registerAction (" Disable Breakpoint" );
867+
875868 context->globalActions ()->bindAction (" Disable Breakpoint" ,
876869 UIAction (
877870 [=](const UIActionContext& ctxt) {
@@ -881,24 +874,82 @@ void GlobalDebuggerUI::SetupMenu(UIContext* context)
881874 if (!controller)
882875 return ;
883876
877+ auto [hasBreakpoint, isEnabled] = getBreakpointEnabledState (ctxt.binaryView , ctxt.address );
884878 bool isAbsoluteAddress = controller->IsConnected ();
879+
885880 if (isAbsoluteAddress)
886881 {
887- controller->DisableBreakpoint (ctxt.address );
882+ if (isEnabled)
883+ controller->DisableBreakpoint (ctxt.address );
884+ else
885+ controller->EnableBreakpoint (ctxt.address );
888886 }
889887 else
890888 {
891889 std::string filename = controller->GetInputFile ();
892890 uint64_t offset = ctxt.address - controller->GetViewFileSegmentsStart ();
893891 ModuleNameAndOffset info = {filename, offset};
894- controller->DisableBreakpoint (info);
892+ if (isEnabled)
893+ controller->DisableBreakpoint (info);
894+ else
895+ controller->EnableBreakpoint (info);
895896 }
896897 },
897898 [=](const UIActionContext& ctxt) {
898- return ctxt.binaryView && hasEnabledBreakpoint (ctxt.binaryView , ctxt.address );
899+ auto [hasBreakpoint, isEnabled] = getBreakpointEnabledState (ctxt.binaryView , ctxt.address );
900+ return ctxt.binaryView && hasBreakpoint && isEnabled;
899901 }));
902+
903+ debuggerMenu->addAction (" Enable Breakpoint" , " Breakpoint" );
900904 debuggerMenu->addAction (" Disable Breakpoint" , " Breakpoint" );
901905
906+ // Register "Solo Breakpoint" action
907+ UIAction::registerAction (" Solo Breakpoint" );
908+ context->globalActions ()->bindAction (" Solo Breakpoint" ,
909+ UIAction (
910+ [=](const UIActionContext& ctxt) {
911+ if (!ctxt.binaryView )
912+ return ;
913+ auto controller = DebuggerController::GetController (ctxt.binaryView );
914+ if (!controller)
915+ return ;
916+
917+ // Get the current address breakpoint location
918+ bool isAbsoluteAddress = controller->IsConnected ();
919+ ModuleNameAndOffset currentInfo;
920+ if (!isAbsoluteAddress)
921+ {
922+ std::string filename = controller->GetInputFile ();
923+ uint64_t offset = ctxt.address - controller->GetViewFileSegmentsStart ();
924+ currentInfo = {filename, offset};
925+ }
926+
927+ // Disable all breakpoints
928+ std::vector<DebugBreakpoint> breakpoints = controller->GetBreakpoints ();
929+ for (const auto & bp : breakpoints)
930+ {
931+ ModuleNameAndOffset info;
932+ info.module = bp.module ;
933+ info.offset = bp.offset ;
934+ controller->DisableBreakpoint (info);
935+ }
936+
937+ // Enable the current breakpoint
938+ if (isAbsoluteAddress)
939+ {
940+ controller->EnableBreakpoint (ctxt.address );
941+ }
942+ else
943+ {
944+ controller->EnableBreakpoint (currentInfo);
945+ }
946+ },
947+ [=](const UIActionContext& ctxt) {
948+ auto [hasBreakpoint, isEnabled] = getBreakpointEnabledState (ctxt.binaryView , ctxt.address );
949+ return ctxt.binaryView && hasBreakpoint;
950+ }));
951+ debuggerMenu->addAction (" Solo Breakpoint" , " Breakpoint" );
952+
902953 UIAction::registerAction (" Connect to Debug Server" );
903954 context->globalActions ()->bindAction (" Connect to Debug Server" ,
904955 UIAction (
0 commit comments