ZHCUAQ1F july 2015 – april 2023
入口挂钩是程序中每个函数进入时调用的例程。出口挂钩是每个函数退出时调用的例程。挂钩的应用包括调试、跟踪、分析和检查栈溢出。使用以下选项启用入口和出口挂钩:
--entry_hook[=name] | 启用入口挂钩。若已指定,挂钩函数被称为name。否则,默认的入口挂钩函数名称为 __entry_hook。 |
--entry_parm{=name| address|none} |
指定挂钩函数的参数。name 参数指定调用函数的名称作为参数传递给挂钩函数。在这种情况下,挂钩函数的签名为:void hook(const char *name); address 参数指定调用函数的地址传递给挂钩函数。在这种情况下,挂钩函数的签名为:void hook(void (*addr)()); none 参数指定调用挂钩函数时不带参数。这是默认设置。在这种情况下,挂钩函数的签名为:void hook(void); |
--exit_hook[=name] | 启用出口挂钩。若已指定,挂钩函数被称为name。否则,默认的出口挂钩函数名称为 __exit_hook。 |
--exit_parm{=name| address|none} |
指定挂钩函数的参数。name 参数指定调用函数的名称作为参数传递给挂钩函数。在这种情况下,挂钩函数的签名为:void hook(const char *name); address 参数指定调用函数的地址传递给挂钩函数。在这种情况下,挂钩函数的签名为:void hook(void (*addr)()); none 参数指定调用挂钩函数时不带参数。这是默认设置。在这种情况下,挂钩函数的签名为:void hook(void); |
挂钩选项的存在创建了带有给定签名的挂钩函数的隐式声明。如果挂钩函数的声明或定义出现在使用这些选项编译的编译单元中,则其必须与上面列出的签名一致。
在 C++ 中,挂钩声明为 extern "C"。因此,可以在 C(或汇编)中定义挂钩,而不必担心名称改编问题。
挂钩可以声明为内联,在这种情况下,编译器会尝试使用与其他内联函数相同的标准来内联这些挂钩。
入口挂钩和出口挂钩是相互独立的。可以启用一个但不启用另一个,或同时启用两个。同一个函数可以同时用作入口挂钩和作出口挂钩。
必须小心避免对挂钩函数进行递归调用。挂钩函数不应调用本身插入了挂钩调用的任何函数。为了防止这种情况,不会为内联函数或挂钩函数本身生成挂钩。
可以使用 --remove_hooks_when_inlining 选项删除优化器自动内联的函数的入口/出口挂钩。
有关 NO_HOOKS pragma 的信息,请参阅节 7.9.26。