我对此只有一些粗略的想法,所以我想有一些更实用的想法。 Linux,Unix和Windows的想法都是受欢迎的。
我头脑中的粗略想法是:
探查器在目标进程中设置某种类型的计时器和计时器中断处理程序。当其处理程序获得控制权时,它会读取并保存指令指针寄存器的值。当完成采样时,它会计算每个IP寄存器值的出现次数,然后我们就可以知道所有采样的程序地址中的“最佳击中者”。
但我实际上并不知道该怎么做。有人能给我一些基本但实用的想法吗?例如,总是使用什么样的计时器(或等效的)?如何读取IP reg值? (我认为当执行进入探查器的处理程序例程时,IP应指向处理程序的入口,而不是指向目标程序中的某个位置,因此我们不能简单地读取当前的IP值)
感谢您的回答!
感谢Peter Cordes和Mike Dunlavey的回答。
彼得的回答讲述了如何读取其他过程的寄存器和内存。现在我意识到探测器不必在目标进程内“执行”,而只是从外部使用ptrace(2)读取目标的reg / mem。它甚至不必暂停目标,因为ptrace无论如何都会这样做。
迈克的回答表明,对于性能分析,计算堆栈跟踪的出现比计算IP寄存器值更有意义,因为后者在采样时执行系统模块时可能会提供过多的噪声信息
非常感谢你们!
答案 0 :(得分:4)
对你来说,这对你有好处。建议 - don't try to mimic gprof。
您需要做的是随机或伪随机时间对调用堆栈进行采样,而不仅仅是IP。
第一个原因 - I / O和系统调用可以深深埋藏在应用程序中并且花费大部分时间,在此期间IP无意义但堆栈是有意义的。 (“CPU剖析器”只是闭上眼睛。)
第二个原因 - 看IP就像试图通过观察尾巴上的毛发来了解马。要分析程序的性能,您需要知道为什么花费的时间,而不仅仅是它。堆栈告诉为什么。
gprof 的另一个问题是,人们认为你需要大量的样本 - 对于统计精度越多越好。 但是假设你正在寻找大海捞针,它的移除几乎没有任何东西 - 换句话说你假设(女孩/女孩程序员)那里没有什么大,就像一头牛在下面干草。 好吧,我从来没有见过没有干奶牛的软件,并且不需要大量的样本来找到它们。
如何获取样本:定时器中断和读取堆栈(二进制)只是一个技术问题。我想了很久以前怎么做的。你也可以。每个调试器都能做到。但要将其转换为代码名称和位置需要映射文件或类似的东西,这通常意味着调试构建(未优化)。您可以从优化的代码中获取映射文件,但优化器已经对代码进行了加密,因此很难理解。
在非优化代码中采样是否值得?我是这么认为的,因为有两种加速,编译器可以做的,以及你可以做的但编译器不能做的。后者是奶牛。 因此,我和许多其他程序员首先要做的是使用随机采样对未优化代码进行性能调优。当所有的奶牛都出来之后,打开优化器,让编译器发挥其神奇作用。