@@ -23,7 +23,7 @@ limitations under the License.
2323using namespace BinaryNinja ;
2424using namespace BinaryNinjaDebuggerAPI ;
2525
26- constexpr int STATUS_STRING_MAX_LEN = 50 ;
26+ constexpr int STATUS_STRING_MAX_LEN = 100 ;
2727
2828DebuggerStatusBarWidget::DebuggerStatusBarWidget (QWidget* parent, ViewFrame* frame, BinaryViewRef data) :
2929 QWidget(parent), m_parent(parent), m_view(frame)
@@ -105,7 +105,71 @@ void DebuggerStatusBarWidget::updateStatusText(const DebuggerEvent& event)
105105 {
106106 DebugStopReason reason = event.data .targetStoppedData .reason ;
107107 const std::string reasonString = DebuggerController::GetDebugStopReasonString (reason);
108- setStatusText (QString::fromStdString (fmt::format (" Stopped ({})" , reasonString)));
108+
109+ std::string statusMessage = fmt::format (" Stopped ({})" , reasonString);
110+
111+ // Add address and symbol information if debugger is available
112+ if (m_debugger) {
113+ // Get current instruction pointer
114+ uint64_t currentIP = m_debugger->IP ();
115+
116+ // Get the current thread's stack frames to retrieve function information
117+ // (same approach as stack trace widget)
118+ auto activeThread = m_debugger->GetActiveThread ();
119+ auto frames = m_debugger->GetFramesOfThread (activeThread.m_tid );
120+ std::string locationString;
121+
122+ if (!frames.empty ()) {
123+ // Use the first frame (current execution context) for function information
124+ const auto & currentFrame = frames[0 ];
125+
126+ // Format function + offset the same way as stack trace widget
127+ auto trimmedFunctionName = currentFrame.m_functionName ;
128+ auto prefix = currentFrame.m_module + ' !' ;
129+ if (trimmedFunctionName.compare (0 , prefix.size (), prefix) == 0 )
130+ trimmedFunctionName.erase (0 , prefix.size ());
131+
132+ // Calculate offset from function start
133+ uint64_t offset = currentFrame.m_pc - currentFrame.m_functionStart ;
134+ if (offset != 0 && !trimmedFunctionName.empty ()) {
135+ locationString = fmt::format (" at 0x{:x} ({} + 0x{:x})" , currentIP, trimmedFunctionName, offset);
136+ } else if (offset == 0 && !trimmedFunctionName.empty ()) {
137+ locationString = fmt::format (" at 0x{:x} ({})" , currentIP, trimmedFunctionName);
138+ } else {
139+ // Fall back to module + offset when function info is not available
140+ auto moduleInfo = m_debugger->AbsoluteAddressToRelative (currentIP);
141+ if (!moduleInfo.module .empty ()) {
142+ // Extract just the filename from the full path
143+ std::string moduleName = moduleInfo.module ;
144+ size_t lastSlash = moduleName.find_last_of (" /\\ " );
145+ if (lastSlash != std::string::npos) {
146+ moduleName = moduleName.substr (lastSlash + 1 );
147+ }
148+ locationString = fmt::format (" at 0x{:x} ({} + 0x{:x})" , currentIP, moduleName, moduleInfo.offset );
149+ } else {
150+ locationString = fmt::format (" at 0x{:x} (?? + 0x{:x})" , currentIP, currentIP);
151+ }
152+ }
153+ } else {
154+ // Fall back to module + offset when no frames are available
155+ auto moduleInfo = m_debugger->AbsoluteAddressToRelative (currentIP);
156+ if (!moduleInfo.module .empty ()) {
157+ // Extract just the filename from the full path
158+ std::string moduleName = moduleInfo.module ;
159+ size_t lastSlash = moduleName.find_last_of (" /\\ " );
160+ if (lastSlash != std::string::npos) {
161+ moduleName = moduleName.substr (lastSlash + 1 );
162+ }
163+ locationString = fmt::format (" at 0x{:x} ({} + 0x{:x})" , currentIP, moduleName, moduleInfo.offset );
164+ } else {
165+ locationString = fmt::format (" at 0x{:x} (?? + 0x{:x})" , currentIP, currentIP);
166+ }
167+ }
168+
169+ statusMessage += locationString;
170+ }
171+
172+ setStatusText (QString::fromStdString (statusMessage));
109173 break ;
110174 }
111175 case TargetExitedEventType:
0 commit comments