Skip to content

Commit

Permalink
patch to restore the breakpoint instruction after it is replaced with…
Browse files Browse the repository at this point in the history
… the original instruction.
  • Loading branch information
yahiafarghaly committed Nov 11, 2017
1 parent e778a0b commit ab78fbb
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 16 deletions.
8 changes: 0 additions & 8 deletions bugs.md

This file was deleted.

4 changes: 3 additions & 1 deletion debugging-examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
add_executable(helloworld helloworld.cpp)
add_executable(calculator calculator.cpp)
add_executable(single-step single-step.cpp)
add_executable(loop loop.c)

set_target_properties(helloworld PROPERTIES COMPILE_FLAGS "-g")
set_target_properties(calculator PROPERTIES COMPILE_FLAGS "-g")
set_target_properties(single-step PROPERTIES COMPILE_FLAGS "-g")
set_target_properties(single-step PROPERTIES COMPILE_FLAGS "-g")
set_target_properties(loop PROPERTIES COMPILE_FLAGS "-g")
12 changes: 12 additions & 0 deletions debugging-examples/loop.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

void main()
{
int x,y,z;
x = y = 4;
int i = 5;
while(i > 0)
{
z = x + y;
--i;
}
}
28 changes: 28 additions & 0 deletions src/debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ void debugger::run() {
}

char* line = nullptr;
this->pLastActivatedBreakPoint = nullptr;
// use linenoise for making a nice command line prompt for the debugger.
while((line = linenoise("tdbg> ")) != nullptr) {
if(!handle_command(line)) break;
Expand Down Expand Up @@ -173,6 +174,22 @@ bool debugger::handle_command(const std::string& line) {
*/
void debugger::continue_execution()
{
// To return the breakpoint INT3 instruction again for the last restored instruction.
// Simply, before we go, we return the user breakpoint again.
if (pLastActivatedBreakPoint != nullptr)
{
if (pLastActivatedBreakPoint->is_enabled())
{
// single step after the restored location.
ptrace(PTRACE_SINGLESTEP, m_pid, nullptr, nullptr);
// absorb the SIGTRAP due to single step.
wait_for_signal();
// restore INT3 instruction by inserting a breakpoint again.
pLastActivatedBreakPoint->enable();
}
// return to the origianl status since INT3 is back.
pLastActivatedBreakPoint = nullptr;
}
// Resume the execution of the debugee program.
ptrace(PTRACE_CONT, m_pid, nullptr, nullptr);
int signal_status = wait_for_signal();
Expand All @@ -195,6 +212,17 @@ void debugger::continue_execution()
// Set RIP reg to the decrement rip value so the debugger points to current restored instruction.
ptrace(PTRACE_POKEUSER, m_pid, 8 * RIP, rip);
printf("Process %d stopped at 0x%lx\n", m_pid, rip);

/* Store the location of breakpoint of the restored instruction in case
the user issued a debugger command "continue" again. And before we continue,
we restore the breakpoint INT3 instruction again.
Imaging the case of a breakpoint inside a loop ! if we haven't stored the last
breakpoint address which we restored its original instruction, we wouldn't able
to break at it again. not just a loop, a recursive function as an example
will work ... etc.
*/
this->pLastActivatedBreakPoint = &m_breakpoints[rip];
}
else
{
Expand Down
4 changes: 3 additions & 1 deletion src/debugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ class debugger {
/* An un-order map of breakpoint objects to be access by its addresses hashes.
m_breakpoints[breakpoint address] -> breakpoint object. */
std::unordered_map<std::intptr_t, breakpoint> m_breakpoints;
// For restoring INT3 instruction after we replaced it with the original instruction.
breakpoint* pLastActivatedBreakPoint;
// To determine if traced process is runnable or not.
bool debuggee_captured;

Expand All @@ -63,7 +65,7 @@ class debugger {
// Start the debuggee program
bool run_traced_process();
// Go to the next instruction.
void next_instruction();
void next_instruction();
};

#endif /* __DEBUGGER_H */
10 changes: 10 additions & 0 deletions todo
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# TODO List

- [x] Re-run debuggee after its termination(run command)
- [x] Disable debugger commands if debuggee is terminated.
- [ ] debuggee args are not supported(not even been read)
- [ ] check for debugger command argc (each one in general).
- [x] make sure the breakpoint work if a loop exist.
- [ ] improve the displayed format of **register dump** command.
- [ ] handle mis writting of break 0x**Address** command, if ***0x*** is not exist case and so on.
- [ ] add command to delete a breakpoint by address.
6 changes: 0 additions & 6 deletions todo.md

This file was deleted.

File renamed without changes.

0 comments on commit ab78fbb

Please sign in to comment.