0

我有一个没有给出正确输出的库。我猜这可能是写违规,并将其重点放在这部分代码上:

void Page::build_default_frame(PosType genome_display_length)
{
    Frame* frame = new Frame(*this,
                             margin_left,
                             margin_top,
                             width - margin_left - margin_right,
                             genome_display_length);
    default_frame = frame;
    frames.insert(default_frame);
}

default_frame是一个推动力intrusive_ptr<Frame>

在执行语句之前default_frame = frame,object 的内容frame是可以的,但之后,它的内容被修改为怪异的值。所以我在对象的两个成员变量上设置了两个手表frame

(gdb) watch -l frame->genome_scale.genome_display_length 
Hardware watchpoint 4: -location frame->genome_scale.genome_display_length
(gdb) watch -l frame->genome_scale.frame_width 
Hardware watchpoint 5: -location frame->genome_scale.frame_width

然后继续。它突然报告对这些地址的写操作:

(gdb) c
Continuing.
Hardware watchpoint 4: -location frame->genome_scale.genome_display_length

Old value = 1000
New value = 16
_dl_runtime_resolve () at ../sysdeps/x86_64/dl-trampoline.S:39
39  ../sysdeps/x86_64/dl-trampoline.S: No such file or directory.
(gdb) bt
#0  _dl_runtime_resolve () at ../sysdeps/x86_64/dl-trampoline.S:39
#1  0x00007ffff7b93dd0 in geno_eye::Page::build_default_frame (this=0x6071b0, genome_display_length=1000)
    at /home/yangxi/projects/GenoEye/src/geno_eye/Page.cpp:127
#2  0x00007ffff7b93cc1 in geno_eye::Page::Page (this=0x6071b0, context=0x607750, width=300, height=300, 
    genome_display_length=1000) at /home/yangxi/projects/GenoEye/src/geno_eye/Page.cpp:29
#3  0x00000000004016b8 in geno_eye::__tester__::run (this=0x7fffffffe1c8)
    at /home/yangxi/projects/GenoEye/t/t_page.cpp:15
#4  0x00000000004015d1 in main () at /home/yangxi/projects/GenoEye/t/t_page.cpp:36
(gdb) c
Continuing.
Hardware watchpoint 5: -location frame->genome_scale.frame_width

Old value = 240
New value = 3.1228427039313504e-317
_dl_runtime_resolve () at ../sysdeps/x86_64/dl-trampoline.S:40
40  in ../sysdeps/x86_64/dl-trampoline.S
(gdb) bt
#0  _dl_runtime_resolve () at ../sysdeps/x86_64/dl-trampoline.S:40
#1  0x00007ffff7b93dd0 in geno_eye::Page::build_default_frame (this=0x6071b0, genome_display_length=1000)
    at /home/yangxi/projects/GenoEye/src/geno_eye/Page.cpp:127
#2  0x00007ffff7b93cc1 in geno_eye::Page::Page (this=0x6071b0, context=0x607750, width=300, height=300, 
    genome_display_length=1000) at /home/yangxi/projects/GenoEye/src/geno_eye/Page.cpp:29
#3  0x00000000004016b8 in geno_eye::__tester__::run (this=0x7fffffffe1c8)
    at /home/yangxi/projects/GenoEye/t/t_page.cpp:15
#4  0x00000000004015d1 in main () at /home/yangxi/projects/GenoEye/t/t_page.cpp:36

这两个旧值是这两个成员变量的正确值。这个写操作是在执行=boost intrusive_ptr 函数之前发生的,因为我按了几十个“next”,代码还在dl-trampoline.S文件中。

(gdb) n
41  in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
42  in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
43  in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
44  in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
45  in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
46  in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
47  in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
48  in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
49  in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
50  in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
51  in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
52  in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
53  in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
54  in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
56  in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
boost::intrusive_ptr<geno_eye::Frame>::operator= (this=0x6071b0, rhs=0x3e8)
    at /usr/include/boost/smart_ptr/intrusive_ptr.hpp:134
134     {

什么是dl-trampoline.S?为什么它会默默地写在我的对象的内存上?

除此之外,我还运行 valgrind:

$ valgrind ./t_page

但是,它不是无效写入,而是向该对象报告无效读取,这是在对象创建完成后发生的。

4

1 回答 1

1

这是由引用堆栈错误引起的。

Objectgenome_scale持有对 object 的两个成员变量的两个引用frame。当我重建我的代码时,它不小心引用了两个堆栈变量......

所以,也许我应该避免在这种情况下使用引用类型,因为您可以轻松地向它们提供堆栈内容并且不会收到任何警告。

于 2014-05-26T08:29:20.173 回答