zoukankan      html  css  js  c++  java
  • [开源项目发布]Observer:根据map文件测试程序在运行中各个函数的运行时间

    寒假断断续续写这个大概有小半个月了,过个年耽误了几天。

    这两天清理了一些bug,整理了代码,打算发出来。

    Observer是基于微软的detour3.0写的。

    适用对象,c/c++编写成的exe文件(需要生成map文件)

    下载Observer地址:http://pan.baidu.com/share/link?shareid=281171&uk=2133448544

    下载源码地址(vs2008工程):https://github.com/youzhonghui/Observer

    BUG可以发到http://1.obser.sinaapp.com/

    如果要编译此源码,需要将detour3.0的include和lib.X86中的文件分别复制到 vs2008的安装目录 Microsoft Visual Studio 9.0\VC 下面的 include 和 lib 文件夹下。

    下面有使用指南。

    原理简介:

    在程序link的阶段,可以选择让连接器生成map文件。map文件有函数名和函数期望载入地址等信息。而程序在载入的时候基本是不会发生重定位的(exe部分),所以根据这个信息,就可以利用detour注入dll改变函数的流程。

    如果要看代码,注意下面几点便于代码理解:

    1.只有自己编写的函数是Observer的测试对象,计时规则等可以看看下面的《Observer使用指南》。

    2.测试对象的个数是不确定的,所以需要在运行的时候动态生成执行代码来对应每一个函数。(曾想过用一个函数套住所有的函数,但是这样做会比较复杂而且效率较低)

    3.生成执行代码的方法是先写一个函数为"模板",然后每次拷贝这个模板的代码,再在需要改动的地方修改(在模板中做标记)

    4.”模板"即为myFunc函数。会调用QueryPerformanceCounter作为计时器。调用函数用ret而不是call ( - -|| call要计算相对距离,ret可以用绝对地址)

    5.要小心维护栈平衡,并且要先保存下会被修改寄存器,因为测试的函数是什么参数,是fastcall还是stdcall,返回值有没有用到栈等等都是不知道的,我要做的就是小心翼翼地把原来的状态都保存下来,之后再改回去。

    《Observer使用指南》:

    作者:南树
    博客:http://www.cnblogs.com/nanshu/
    Observer论坛:http://1.obser.sinaapp.com/
     
     
    本软件绿色,无需安装。
     
    运行时需要
        Observer_shell_v2.0.exe
        Observer-kernel_v1.0.dll
        withdll.exe
    三个文件在同一个目录下。
     
    使用方法:
        运行Observer_shell_v2.0.exe
        可以看到等待输入。
        将需要测试的目标exe文件拖入黑框,回车即可。
        保证map文件和目标exe文件在同一个目录下
        运行结束以后会在目标文件目录下生成 name_result.txt文件,即为测试结果。
        在sample文件夹中有供尝试的test。运行Observer_shell_v2.0.exe后将test拉入黑框回车,运行结束后会生成相应的结果文件。
        
    生成map文件的方法:
        map是在link阶段生成的,如果用IDE的话,一般可以在工程属性的link页找到。
        如:vc6是 项目 -> 设置 -> 连接 -> 产生map文件
            vs2008是 properties -> linker -> Debugging -> Generate Map File
        其他IDE或者用makefile的可以上网查查。
     
    注意:
        不要在路径中出现空格
        在name_result.txt的第一行有Minimum interval
            例如:Minimum interval:0.000411 ms
        表示如果一个函数一次执行期间所用时间小于0.000411 ms,所有时间将不会被记录,在结果中对于函数的调用时间为 0
        Frequency 表示函数被调用的次数
        Time      表示函数运行的时间。注意,请认真看下面的计时规则
        有可能您的平台不支持高精度计时器(在name_result.txt第一行显示Do not support timer),那么就无法使用本程序。
        如果你写的函数比较简短,有可能会被编译器当做内联函数优化掉,不会出现在map文件中。可以在编译器的优化选项中选择去掉此项。
        vc可以用#pragma optimize("",off)来取消优化
     
    计时规则:
        测试的对象是自己写的函数,对于调用的API或者c标准库中的函数不作为测试对象。
        如果A,B函数都是测试对象,A中调用了B,那么A最后的时间是A开始到结束的时间 - B开始到结束的时间。递归亦是如此统计,不会叠加。
  • 相关阅读:
    Karen and Game CodeForces
    Array and Segments (Easy version) CodeForces
    Diverse Garland CodeForces
    Nice Garland CodeForces
    Divisors of Two Integers CodeForces
    Two distinct points CodeForces
    Unique Snowflakes UVA
    Codeforces Round #534 (Div. 2)D. Game with modulo-1104-D(交互+二分+构造)
    关于排列组合问题的基础补充
    杭电 rescue(经典广搜)(深搜广搜对比)
  • 原文地址:https://www.cnblogs.com/nanshu/p/2915696.html
Copyright © 2011-2022 走看看