gpt4 book ai didi

c++ - 根据参数值进行检测

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:46:06 25 4
gpt4 key购买 nike

在我正在进行的项目中,我们同意仅使用返回错误代码(无异常)的函数来处理错误。

为了不让调试消息“污染”我的代码,我正在研究基于检测的解决方案(受 this post 启发)。

我没有使用整数作为错误代码,而是将其封装在一个类中:

// File rc.h
class rc
{
public:
rc(int) __attribute__((no_instrument_function));
rc& operator=(rc);
private:
int value;
};

然后将这些运算符和检测函数定义为:

// File rc.cc
#include <stdio.h>
#include <time.h>
#include "rc.h"

static FILE *fp_trace;
static int isError;

extern "C"
{

void __attribute__ ((constructor)) trace_begin (void)
{
fp_trace = fopen("trace.out", "w");
isError = 0;
}

void __attribute__ ((destructor)) trace_end (void)
{
if(fp_trace != NULL) {
fclose(fp_trace);
}
}

void __cyg_profile_func_enter (void *func, void *caller) __attribute__((no_instrument_function));
void __cyg_profile_func_exit (void *func, void *caller) __attribute__((no_instrument_function));

void __cyg_profile_func_enter (void *func, void *caller)
{
}

void __cyg_profile_func_exit (void *func, void *caller)
{
if ((fp_trace != NULL) && (isError == 1)) {
fprintf(fp_trace, "x %p %p %lu\n", func, caller, time(NULL));
isError = 0;
}
}
}

rc::rc(int valueIn) :
value(valueIn)
{
}

rc& rc::operator=(rc rcIn)
{
value = rcIn.value;
if (value != 0)
{
isError = 1;
fprintf(fp_trace, "%d\n", value);
}
return *this;
}

但是,为了不打印太多东西,我不想记录返回返回码 0 的函数调用,也就是 isError 标志。

这可以与以下示例一起使用:

#include <cstdlib>
#include <ctime>
#include "rc.h"

rc bar(void)
{
rc result(std::rand() % 3);
return result;
}

int main(void)
{
std::srand (std::time(NULL));
rc returnCode(0);
for (int i=0; i<10; ++i)
{
returnCode = bar();
}
return 0;
}

编译运行

g++ -finstrument-functions -g -c -o rc.o rc.cc 
g++ -g -c -o test.o test.cc
g++ test.o rc.o -o a.out
./a.out

使用给定的脚本读取输出 in the previously mentioned post将导致类似的结果:

Error code 2
rc::operator=(rc) at 2016-07-03T18:32:09+0200, called from main (test.cc:32)

这几乎是我所希望的。但与我只是在 rc foo(void) 中添加测试以测试输出是否为非零然后记录错误的解决方案相比,这只会增加开销(加上由于检查)在发生错误的情况下(希望不要太频繁),我将在每次调用时增加由于检测而产生的开销(加上由于 rc 包装器可能产生的开销,但我可以接受)......

是否有一个我无法想到的解决方案,它不会在参数为零的情况下检测 operator=?由于 rc::value 仅在运行时已知,我不认为带有参数值的模板专门用于 value=0 并且不会对其进行检测案例会起作用。会吗?

有一个额外的约束:检测函数是赋值运算符很重要,因为我想知道调用者,因此我不能添加一些额外的代理级别。


编辑 关于最后一点,我考虑过使赋值运算符内联(而不是检测)并在返回码不为零的情况下调用检测函数,但这不能'不作为 finstrument-function doc page指出:

This instrumentation is also done for functions expanded inline in other functions. The profiling calls will indicate where, conceptually, the inline function is entered and exited.

这样它就不会指向真正的调用者。

最佳答案

解决方案不是依赖检测,而是依赖检测使用的 __builtin_return_address(unsigned int) 函数。

您可以使用此函数获取调用方的返回指针:

rc& rc::operator=(rc rcIn)
{
value = rcIn.value;
if (value != 0)
{
fprintf(fp_trace, "%d %p\n", value, __builtin_return_address(1));
}
return *this;
}

这样你就不需要依赖检测来获取调用方地址,并且会比使用 int 增加很少的开销。

关于c++ - 根据参数值进行检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38172293/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com