Skip to content

Commit

Permalink
Also make the InvokeBackendCommand return the command output for DbgE…
Browse files Browse the repository at this point in the history
…ng adapter. Fix Vector35#591
  • Loading branch information
xusheng6 committed Oct 11, 2024
1 parent d1f0e0e commit 74ef283
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 2 deletions.
17 changes: 16 additions & 1 deletion core/adapters/dbgengadapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1301,9 +1301,13 @@ std::string DbgEngAdapter::InvokeBackendCommand(const std::string& command)
{
if (m_debugControl)
{
m_outputCallbacks.StartOutput();
this->m_debugControl->Execute(DEBUG_OUTCTL_ALL_CLIENTS, command.c_str(), DEBUG_EXECUTE_NO_REPEAT);
m_debugClient->ExitDispatch(reinterpret_cast<PDEBUG_CLIENT>(m_debugClient));
// The output is handled by DbgEngOutputCallbacks::Output()
// The output is handled by DbgEngOutputCallbacks::Output(), and Execute() would not return until all output
// has been dumped, so we can get the full output here
auto ret = m_outputCallbacks.EndOutput();
return ret;
}
return "";
}
Expand Down Expand Up @@ -1450,6 +1454,7 @@ HRESULT DbgEngOutputCallbacks::Output(unsigned long mask, const char* text)
event.type = BackendMessageEventType;
event.data.messageData.message = text;
m_adapter->PostDebuggerEvent(event);
m_output += text;
return S_OK;
}

Expand All @@ -1463,6 +1468,16 @@ unsigned long DbgEngOutputCallbacks::Release()
return 0;
}

void DbgEngOutputCallbacks::StartOutput()
{
m_output.clear();
}

std::string DbgEngOutputCallbacks::EndOutput()
{
return m_output;
}

HRESULT DbgEngOutputCallbacks::QueryInterface(const IID& interface_id, void** _interface)
{
return S_OK;
Expand Down
3 changes: 3 additions & 0 deletions core/adapters/dbgengadapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,16 @@ namespace BinaryNinjaDebugger {
{
private:
DebugAdapter* m_adapter;
std::string m_output;

public:
CALLBACK_METHOD(unsigned long) AddRef() override;
CALLBACK_METHOD(unsigned long) Release() override;
CALLBACK_METHOD(HRESULT) QueryInterface(const IID& interface_id, void** _interface) override;
CALLBACK_METHOD(HRESULT) Output(unsigned long mask, const char* text);
void SetAdapter(DebugAdapter* adapter);
void StartOutput();
std::string EndOutput();
};

class DbgEngInputCallbacks : public IDebugInputCallbacks
Expand Down
10 changes: 9 additions & 1 deletion ui/debugadapterscriptingprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,15 @@ BNScriptingProviderExecuteResult DebugAdapterScriptingInstance::ExecuteScriptInp
auto trimmedInput = input;
trimmedInput.erase(trimmedInput.find_last_not_of('\n') + 1);
auto ret = m_controller->InvokeBackendCommand(trimmedInput);
Output(ret);
// Do not output the returned string if it is DbgEng, since the output from DbgEng backend is already handled
// by the BackendMessageEventType event
if ((m_controller->GetAdapterType() != "DBGENG") && (m_controller->GetAdapterType() != "DBGENG_TTD")
&& (m_controller->GetAdapterType() != "LOCAL_WINDOWS_KERNEL")
&& (m_controller->GetAdapterType() != "WINDOWS_KERNEL")
&& (m_controller->GetAdapterType() != "WINDOWS_DUMP_FILE"))
{
Output(ret);
}
return SuccessfulScriptExecution;
}
return InvalidScriptInput;
Expand Down

0 comments on commit 74ef283

Please sign in to comment.