C ++抓取悬挂引用 [英] C++ catching dangling reference

查看:185
本文介绍了C ++抓取悬挂引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设下面的代码

struct S {
    S(int & value): value_(value) {}
    int & value_;
};

S function() {
    int value = 0;
    return S(value);   // implicitly returning reference to local value
}

编译器不会产生警告)

有什么工具可以帮助捕获这些问题

What tools are out there to help catch such problems

推荐答案

有基于运行时的解决方案,它使代码检查无效的指针访问。我只使用mudflap到目前为止(从4.0版本集成在GCC)。 mudflap试图跟踪代码中的每个指针(和引用),并检查每个访问,如果指针/引用实际指向其基类型的活动对象。下面是一个示例:

There are runtime based solutions which instrument the code to check invalid pointer accesses. I've only used mudflap so far (which is integrated in GCC since version 4.0). mudflap tries to track each pointer (and reference) in the code and checks each access if the pointer/reference actually points to an alive object of its base type. Here is an example:

#include <stdio.h>
struct S {
    S(int & value): value_(value) {}
    int & value_;
};

S function() {
    int value = 0;
    return S(value);   // implicitly returning reference to local value
}
int main()
{
    S x=function();
    printf("%s\n",x.value_); //<-oh noes!
}

在启用mudflap的情况下进行编译:

Compile this with mudflap enabled:

g++ -fmudflap s.cc -lmudflap

并运行给出:

$ ./a.out
*******
mudflap violation 1 (check/read): time=1279282951.939061 ptr=0x7fff141aeb8c size=4
pc=0x7f53f4047391 location=`s.cc:14:24 (main)'
      /opt/gcc-4.5.0/lib64/libmudflap.so.0(__mf_check+0x41) [0x7f53f4047391]
      ./a.out(main+0x7f) [0x400c06]
      /lib64/libc.so.6(__libc_start_main+0xfd) [0x7f53f358aa7d]
Nearby object 1: checked region begins 332B before and ends 329B before
mudflap object 0x703430: name=`argv[]'
bounds=[0x7fff141aecd8,0x7fff141aece7] size=16 area=static check=0r/0w liveness=0
alloc time=1279282951.939012 pc=0x7f53f4046791
Nearby object 2: checked region begins 348B before and ends 345B before
mudflap object 0x708530: name=`environ[]'
bounds=[0x7fff141aece8,0x7fff141af03f] size=856 area=static check=0r/0w liveness=0
alloc time=1279282951.939049 pc=0x7f53f4046791
Nearby object 3: checked region begins 0B into and ends 3B into
mudflap dead object 0x7089e0: name=`s.cc:8:9 (function) int value'
bounds=[0x7fff141aeb8c,0x7fff141aeb8f] size=4 area=stack check=0r/0w liveness=0
alloc time=1279282951.939053 pc=0x7f53f4046791
dealloc time=1279282951.939059 pc=0x7f53f4046346
number of nearby objects: 3
Segmentation fault

需要考虑几点:


  1. mudflap可以精确调整在什么应该检查和做。有关详情,请阅读 http://gcc.gnu.org/wiki/Mudflap_Pointer_Debugging

  2. 默认行为是在违规时引发SIGSEGV,这意味着您可以在调试器中找到违例。

  3. mudflap可能是一个。子,特别是当你与未编译的mudflap支持的库交互时。

  4. 它不会在创建悬挂引用的地方(返回S(值)),只有当引用被取消引用时。如果你需要这个,那么你需要一个静态分析工具。

  1. mudflap can be fine tuned in what exactly it should check and do. read http://gcc.gnu.org/wiki/Mudflap_Pointer_Debugging for details.
  2. The default behaviour is to raise a SIGSEGV on a violation, this means you can find the violation in your debugger.
  3. mudflap can be a bitch, in particular when your are interacting with libraries that are not compiled with mudflap support.
  4. It wont't bark on the place where the dangling reference is created (return S(value)), only when the reference is dereferenced. If you need this, then you'll need a static analysis tool.

需要考虑的一个问题是,向S()的复制构造函数添加一个 NON-PORTABLE 检查,该函数声明value_不绑定到具有较短寿命的整数(例如,如果*这位于堆栈的较旧插槽,它是绑定到它的整数)。这是高机器具体的,可能是棘手的当然,但应该是确定,只要它只是为了调试。

P.S. one thing to consider was, to add a NON-PORTABLE check to the copy constructor of S(), which asserts that value_ is not bound to an integer with a shorter life span (for example, if *this is located on an "older" slot of the stack that the integer it is bound to). This is higly-machine specific and possibly tricky to get right of course, but should be OK as long it's only for debugging.

这篇关于C ++抓取悬挂引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆