Supposed I have a function void Myclass::func(x)
, and various other code make thousands of calls to it. Now I want to know some stats of the argument x
, for example, the average, max, min, or even a distribution graph.
void Myclass::func(int x) {
while(foo.doFancyStuff(x)) {
// ...
}
}
Here's some ad-hoc methods that come to my mind:
x
to log. Then use external tools/scripts to analyze them.
x
into external log or file on filesystem is slow.Myclass
.
Otherclass::doOtherStuff(y)
? And bad integration, because that stats code should not be coupled with the Myclass
itself.Is there any tool/library to do this? I'm using Visual Studio on Windows, so would like an answer usable for this platform. Cross-platform tools are welcome, too.
Here is an example using the scripting API of lldb
(which works on Windows, too). Take this trivial program,
void func(int x) {}
int main(int, char **)
{
for (int i = 0; i < 1000; ++i)
func(i);
}
which you can analyze with such a script
import lldb
import os
fArgs = []
def analyzeFrame(frame, bpLocation, dict):
variables = frame.GetVariables(True, False, False, False)
x = variables.GetValueAtIndex(0).GetValueAsSigned()
fArgs.append(x)
return False
debugger = lldb.SBDebugger.Create()
debugger.SetAsync(False)
target = debugger.CreateTargetWithFileAndArch("pathToYourExecutable", "")
bp = target.BreakpointCreateByName("func", 4, lldb.SBFileSpecList(), lldb.SBFileSpecList())
bp.SetScriptCallbackFunction("analyzeFrame")
process = target.Launch(target.GetDebugger().GetListener(), [], [],
None, None, None, os.getcwd(), 0, False, lldb.SBError())
print("max: {}".format(max(fArgs)))
print("min: {}".format(min(fArgs)))
You need to make sure the python interpreter finds the lldb
module. The path can be seen by executing lldb -P
on the command line.
Unfortunately, there is no single simple answer. What you want is a variation of instrumentation debugging, which means that someone needs to inject additional code in your class to handle this case.
For a portable way, the only option you have is to add a cache of the previous values, then in your class destructor, output the statistics that you want. The way you cache data is up to you, you can design a simple Stats<>
class, member of the class that you want to monitor and make calls to it to store new values. That would be what I would try first, as it's portable, almost clean and reusable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With