Last active
July 10, 2017 05:41
-
-
Save bibhas/3ae690a2e983b00d96e75d792e92b59c to your computer and use it in GitHub Desktop.
LLDB C++ API function tracer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Scroll to the bottom for the code (tracer.mm) | |
When I run the tracer, the return value (the value of rax after stepping out of the thread) is always zero. | |
I'm breaking on malloc, so the output should be some pointery looking value. I tried with other functions as well, | |
and I get the same issue. I also tried checking for the process state, and that says it's invalid. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Creating debugger... | |
Creating target... | |
Creating breakpoint... | |
Now in function named : malloc in process with pid = 12511 | |
Requested size : 32 | |
Returned : 0 | |
Now in function named : malloc in process with pid = 12511 | |
Requested size : 32 | |
Returned : 0 | |
Now in function named : malloc in process with pid = 12511 | |
Requested size : 32 | |
Returned : 0 | |
Now in function named : malloc in process with pid = 12511 | |
Requested size : 45 | |
Returned : 0 | |
Now in function named : malloc in process with pid = 12511 | |
Requested size : 47 | |
Returned : 0 | |
Now in function named : malloc in process with pid = 12511 | |
Requested size : 46 | |
Returned : 0 | |
Now in function named : malloc in process with pid = 12511 | |
Requested size : 52 | |
Returned : 0 | |
Now in function named : malloc in process with pid = 12511 | |
Requested size : 50 | |
Returned : 0 | |
Now in function named : malloc in process with pid = 12511 | |
Requested size : 48 | |
Returned : 0 | |
Now in function named : malloc in process with pid = 12511 | |
Requested size : 40 | |
Returned : 0 | |
Now in function named : malloc in process with pid = 12511 | |
Requested size : 45 | |
Returned : 0 | |
Now in function named : malloc in process with pid = 12511 | |
Requested size : 47 | |
Returned : 0 | |
Now in function named : malloc in process with pid = 12511 | |
Requested size : 46 | |
Returned : 0 | |
Now in function named : malloc in process with pid = 12511 | |
Requested size : 50 | |
Returned : 0 | |
Now in function named : malloc in process with pid = 12511 | |
Requested size : 48 | |
Returned : 0 | |
Now in function named : malloc in process with pid = 12511 | |
Requested size : 45 | |
Returned : 0 | |
Now in function named : malloc in process with pid = 12511 | |
Requested size : 47 | |
Returned : 0 | |
Now in function named : malloc in process with pid = 12511 | |
Requested size : 50 | |
Returned : 0 | |
Now in function named : malloc in process with pid = 12511 | |
Requested size : 48 | |
Returned : 0 | |
Now in function named : malloc in process with pid = 12511 | |
Requested size : 231 | |
Returned : 0 | |
Now in function named : malloc in process with pid = 12511 | |
Requested size : 32768 | |
Returned : 0 | |
Now in function named : malloc in process with pid = 12511 | |
Requested size : 4096 | |
Returned : 0 | |
Program exited! | |
Done. | |
Terminating debugger... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// tracer.mm | |
#include <iostream> | |
#include <lldb/API/LLDB.h> | |
#include <utils/scope_exit_guard.h> | |
#include <utils/compute.h> | |
int main(int argc, const char **argv) { | |
// Setup debugger environment | |
lldb::SBDebugger::Initialize(); | |
scope_exit_guard_t guard([&] { | |
std::cout << "Terminating debugger..." << std::endl; | |
lldb::SBDebugger::Terminate(); | |
}); | |
// Create debugger | |
lldb::SBDebugger debugger = COMPUTE({ | |
std::cout << "Creating debugger..." << std::endl; | |
lldb::SBDebugger resp = lldb::SBDebugger::Create(); | |
assert(resp.IsValid() && "Could not create a valid debugger!"); | |
resp.SetAsync(false); | |
return resp; | |
}); | |
// Create target | |
lldb::SBTarget target = COMPUTE({ | |
std::cout << "Creating target..." << std::endl; | |
lldb::SBError error; | |
lldb::SBTarget resp = debugger.CreateTarget( | |
"/bin/ls", "x86_64", NULL, true, error | |
); | |
assert(error.Success() && "Failed to create target!"); | |
assert(resp.IsValid() && "Target created but is invalid!"); | |
return resp; | |
}); | |
// Add breakpoints | |
lldb::SBBreakpoint breakpoint = COMPUTE({ | |
std::cout << "Creating breakpoint..." << std::endl; | |
lldb::SBBreakpoint resp = target.BreakpointCreateByName("malloc"); | |
auto callback = [](void *baton, lldb::SBProcess& process, lldb::SBThread& thread, lldb::SBBreakpointLocation& location) -> bool { | |
// Log where we're at | |
lldb::SBFrame frame = thread.GetFrameAtIndex(0); | |
std::cout << "Now in function named : " << frame.GetFunctionName() << " in process with pid = " << process.GetProcessID() << std::endl; | |
// Print the argument | |
// x86_64 calling convention : RDI, RSI, RDX, RCX, R8, R9, XMM0–7 | |
lldb::SBValue rdiValue = frame.FindValue("rdi", lldb::eValueTypeRegister); | |
std::cout << "\tRequested size : " << rdiValue.GetValueAsUnsigned() << std::endl; | |
// Next, step out | |
thread.StepOut(); | |
// Then log return value | |
lldb::SBValue raxValue = frame.FindValue("rax", lldb::eValueTypeRegister); | |
std::cout << "\tReturned : " << raxValue.GetValueAsUnsigned() << std::endl; | |
return true; | |
}; | |
resp.SetCallback(callback, 0); | |
return resp; | |
}); | |
// Launch process | |
lldb::SBProcess process = COMPUTE({ | |
lldb::SBProcess resp = target.LaunchSimple(nullptr, nullptr, "/Users/Bibhas/Desktop"); | |
assert(resp.IsValid() && "Failed to attach to remote process!"); | |
return resp; | |
}); | |
// Poll process for state changes | |
while (1) { | |
lldb::StateType state = process.GetState(); | |
if (state == lldb::eStateStopped) { | |
process.Continue(); | |
} | |
else if (state == lldb::eStateExited) { | |
std::cerr << "Program exited!" << std::endl; | |
break; | |
} | |
} | |
// We're done | |
std::cout << "Done." << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment