Skip to content

Commit

Permalink
Add restart_and_wait API and add a unit test for it. Fix Vector35#608
Browse files Browse the repository at this point in the history
  • Loading branch information
xusheng6 committed Aug 19, 2024
1 parent 4677199 commit f5303e5
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 3 deletions.
1 change: 1 addition & 0 deletions api/debuggerapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,7 @@ namespace BinaryNinjaDebuggerAPI {
DebugStopReason RunToAndWait(uint64_t remoteAddresses);
DebugStopReason RunToAndWait(const std::vector<uint64_t>& remoteAddresses);
DebugStopReason PauseAndWait();
DebugStopReason RestartAndWait();

std::string GetAdapterType();
void SetAdapterType(const std::string& adapter);
Expand Down
6 changes: 6 additions & 0 deletions api/debuggercontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,12 @@ DebugStopReason DebuggerController::PauseAndWait()
}


DebugStopReason DebuggerController::RestartAndWait()
{
return BNDebuggerRestartAndWait(m_object);
}


std::string DebuggerController::GetAdapterType()
{
char* adapter = BNDebuggerGetAdapterType(m_object);
Expand Down
1 change: 1 addition & 0 deletions api/ffi.h
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,7 @@ extern "C"
DEBUGGER_FFI_API BNDebugStopReason BNDebuggerRunToAndWait(
BNDebuggerController* controller, const uint64_t* remoteAddresses, size_t count);
DEBUGGER_FFI_API BNDebugStopReason BNDebuggerPauseAndWait(BNDebuggerController* controller);
DEBUGGER_FFI_API BNDebugStopReason BNDebuggerRestartAndWait(BNDebuggerController* controller);

DEBUGGER_FFI_API char* BNDebuggerGetAdapterType(BNDebuggerController* controller);
DEBUGGER_FFI_API void BNDebuggerSetAdapterType(BNDebuggerController* controller, const char* adapter);
Expand Down
8 changes: 8 additions & 0 deletions api/python/debuggercontroller.py
Original file line number Diff line number Diff line change
Expand Up @@ -1143,6 +1143,14 @@ def pause_and_wait(self) -> None:
"""
dbgcore.BNDebuggerPauseAndWait(self.handle)

def restart_and_wait(self) -> None:
"""
Restart a running target.
The call is blocking and only returns when the target stops again after the restart.
"""
dbgcore.BNDebuggerRestartAndWait(self.handle)

@property
def adapter_type(self) -> str:
"""
Expand Down
17 changes: 15 additions & 2 deletions core/debuggercontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1159,10 +1159,23 @@ std::vector<DebugFrame> DebuggerController::GetFramesOfThread(uint64_t tid)
}


void DebuggerController::Restart()
bool DebuggerController::Restart()
{
if (!m_state->IsConnected())
return false;

std::thread([&]() { RestartAndWait(); }).detach();
return true;
}


DebugStopReason DebuggerController::RestartAndWait()
{
if (!m_state->IsConnected())
return InvalidStatusOrOperation;

QuitAndWait();
Launch();
return LaunchAndWait();
}


Expand Down
3 changes: 2 additions & 1 deletion core/debuggercontroller.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ namespace BinaryNinjaDebugger {

// target control
bool Execute();
void Restart();
bool Restart();
bool ConnectToDebugServer();
bool DisconnectDebugServer();
// Convenience function, either launch the target process or connect to a remote, depending on the selected
Expand Down Expand Up @@ -261,6 +261,7 @@ namespace BinaryNinjaDebugger {
DebugStopReason GoAndWait();
DebugStopReason GoReverseAndWait();
DebugStopReason AttachAndWait();
DebugStopReason RestartAndWait();
DebugStopReason ConnectAndWait();
DebugStopReason StepIntoAndWait(BNFunctionGraphType il = NormalFunctionGraph);
DebugStopReason StepIntoReverseAndWait(BNFunctionGraphType il = NormalFunctionGraph);
Expand Down
6 changes: 6 additions & 0 deletions core/ffi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,12 @@ DebugStopReason BNDebuggerPauseAndWait(BNDebuggerController* controller)
}


DebugStopReason BNDebuggerRestartAndWait(BNDebuggerController* controller)
{
return controller->object->RestartAndWait();
}


char* BNDebuggerGetAdapterType(BNDebuggerController* controller)
{
if (!controller->object->GetState())
Expand Down
20 changes: 20 additions & 0 deletions test/debugger_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,26 @@ def test_thread(self):
self.assertGreater(len(threads), 1)
dbg.quit_and_wait()

def test_restart(self):
fpath = name_to_fpath('helloworld_thread', self.arch)
bv = load(fpath)
dbg = DebuggerController(bv)
self.assertNotIn(dbg.launch_and_wait(), [DebugStopReason.ProcessExited, DebugStopReason.InternalError])

dbg.go()
time.sleep(1)
dbg.pause_and_wait()
self.assertGreater(len(dbg.threads), 1)

ret = dbg.restart_and_wait()
self.assertNotIn(ret, [DebugStopReason.ProcessExited, DebugStopReason.InternalError])

dbg.go()
time.sleep(1)
ret = dbg.restart_and_wait()
self.assertNotIn(ret, [DebugStopReason.ProcessExited, DebugStopReason.InternalError])
dbg.quit_and_wait()

def test_assembly_code(self):
if self.arch == 'x86_64':
fpath = name_to_fpath('asmtest', 'x86_64')
Expand Down

0 comments on commit f5303e5

Please sign in to comment.