在调试中,如何知道对函数的重复调用中参数的统计数据(max-min,average,distribution..)
In debugging, how to know the stats (max-min, average, distribution...) of an argument in a repetitive calls to a function?
假设我有一个函数void Myclass::func(x)
,其他各种代码对它进行了数千次调用。现在我想知道参数x
的一些统计数据,例如平均值、最大值、最小值,甚至分布图。
void Myclass::func(int x) {
while(foo.doFancyStuff(x)) {
// ...
}
}
以下是我想到的一些特殊方法:
- 将
x
的每个值打印到日志中。然后使用外部工具/脚本对其进行分析。- 注意事项:与日志中的其他信息混合。将
x
的每个值写入文件系统上的外部日志或文件是很慢的
- 注意事项:与日志中的其他信息混合。将
- 定义全局变量以存储它们,并在感兴趣的执行结束时进行分析。
- 注意事项:全局变量不好。它们将来会变得令人困惑
- 将它们存储在类别
Myclass
中。- 注意事项:不可重复使用的代码。下次我想分析
Otherclass::doOtherStuff(y)
时呢?以及糟糕的集成,因为统计代码不应该和Myclass
本身耦合
- 注意事项:不可重复使用的代码。下次我想分析
有什么工具/库可以做到这一点吗?我在Windows上使用Visual Studio,所以希望得到一个适用于此平台的答案。跨平台工具也很受欢迎。
下面是一个使用lldb
的脚本API的示例(它也适用于Windows)。以这个琐碎的程序为例,
void func(int x) {}
int main(int, char **)
{
for (int i = 0; i < 1000; ++i)
func(i);
}
你可以用这样的脚本来分析
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)))
您需要确保python解释器找到lldb
模块。可以通过在命令行上执行lldb -P
来查看路径。
不幸的是,没有一个简单的答案。您想要的是一种检测调试的变体,这意味着需要有人在您的类中注入额外的代码来处理这种情况。
对于可移植的方法,唯一的选择是添加以前值的缓存,然后在类析构函数中输出所需的统计信息。缓存数据的方式取决于您自己,您可以设计一个简单的Stats<>
类,它是要监视的类的成员,并对其进行调用以存储新值。这将是我首先尝试的,因为它是便携式的,几乎是干净的,可重复使用的。
相关文章:
- 可变参数模板与使用元组在参数中添加不同的数据对
- 带参数的数据结构的全局声明
- 读取大文件(>2GB)(文本文件包含以太网数据)并通过不同参数随机访问数据的最佳方法是什么?
- 如果参数与数据成员的参数同名,该怎么办?
- 指向(数据)成员的指针作为非类型模板参数,例如具有自动存储持续时间/无链接
- 自动模板参数、数据成员和恒常性
- 使用 std::function 作为具有任意数量参数的数据成员
- 避免在统计数据和重命名之间进行TOCTOU(检查时间,使用时间)
- 使用模板参数添加数据
- 是否有一些有意义的统计数据来证明保持有符号整数算术溢出未定义是合理的
- Magick++ ImageMagick 7.0.5-4 Q16 的统计数据x86_64问题
- 在调试中,如何知道对函数的重复调用中参数的统计数据(max-min,average,distribution..)
- 函数有没有办法自动检测其参数的数据类型?(请不要建议函数重载)
- 添加/删除具有模板参数的数据成员
- 我可以收集mmap读/写统计数据吗
- 巧克力游戏:输入循环,不插入循环或打印游戏统计数据
- Android C++OpenGL:无法找到统计数据
- 如果传递给函数的参数的数据类型是字符串类型,则抛出异常
- 传递参数时数据类型不匹配
- 从表创建统计数据