我遇到了一个c ++ 11程序的奇怪行为,无法弄清楚出了什么问题。请给我一些建议。感谢。
struct memory_layout
{
public:
memory_layout(managed_device d);
scalar<int> s;
};
memory_layout::memory_layout(managed_device d) :
s(d)
{
}
class doer
{
public:
doer();
void go();
private:
managed_device dev;
memory_layout mem;
};
doer::doer():
dev(find_CPU()),
mem(dev)
{
}
void doer::go()
{
task t = copy(10,mem.s);
}
int main(){
doer d;
d.go();
return 0;
}
当它运行复制功能时,它有“分段错误”。
template <typename T>
task copy(const T& source, scalar<T>& sink, const std::vector<task>& deps = {} )
{
return sink.device().create_task( profile::copy<T>(source, sink), deps );
}
Breakpoint 1, doer::go (this=0x7fffffffdc90) at main.cpp:79
79 task t = copy(10,mem.s); // device() original be 0x60f0d0
(gdb) p mem.s.device()
$1 = (cppcl::opencl_1_2::device::managed_device &) @0x7fffffffdc60: {_device = 0x60f0d0}
(gdb) s
std::vector<unsigned long, std::allocator<unsigned long> >::vector (this=0x7fffffffdc50) at /usr/include/c++/4.8.3/bits/stl_vector.h:249
249 : _Base() { }
(gdb)
std::_Vector_base<unsigned long, std::allocator<unsigned long> >::_Vector_base (this=0x7fffffffdc50)
at /usr/include/c++/4.8.3/bits/stl_vector.h:125
125 : _M_impl() { }
(gdb)
std::_Vector_base<unsigned long, std::allocator<unsigned long> >::_Vector_impl::_Vector_impl (this=0x7fffffffdc50)
at /usr/include/c++/4.8.3/bits/stl_vector.h:87
87 : _Tp_alloc_type(), _M_start(0), _M_finish(0), _M_end_of_storage(0)
(gdb)
std::allocator<unsigned long>::allocator (this=0x7fffffffdc50) at /usr/include/c++/4.8.3/bits/allocator.h:113
113 allocator() throw() { }
(gdb)
__gnu_cxx::new_allocator<unsigned long>::new_allocator (this=0x7fffffffdc50) at /usr/include/c++/4.8.3/ext/new_allocator.h:80
warning: Source file is more recent than executable.
80
(gdb)
std::_Vector_base<unsigned long, std::allocator<unsigned long> >::_Vector_impl::_Vector_impl (this=0x7fffffffdc50)
at /usr/include/c++/4.8.3/bits/stl_vector.h:88
88 { }
(gdb)
cppcl::opencl_1_2::device::copy<int> (source=@0x7fffffffdc6c: 10, sink=..., deps=std::vector of length 0, capacity 0)
at /usr/include/cppcl/1.2/device/buffer_templates.h:1233
warning: Source file is more recent than executable.
1233 return sink.device().create_task( profile::copy<T>(source, sink), deps );
(gdb) p sink.device()
$2 = (cppcl::opencl_1_2::device::managed_device &) @0x7fffffffdc60: {_device = 0x0}
进入复制功能后,首先构建“deps”参数,然后将_device值更改为0x0。我无法弄清楚为什么这么开心?
感谢您给我一些建议。
答案 0 :(得分:1)
我假设你没有问你的代码有什么问题,你只是在问自己如何弄清楚你的代码有什么问题。否则,你的问题中没有足够的信息。
这是调试的第一步。您已经发现内存中的一个值正在被更改的明确指示。您在地址managed_device
找到了一个具体对象0x7fffffffdc60
,其中包含一个以某种方式更改的值。
让我使用一个简单的完整程序:
#include <stdio.h>
int *p;
void f() {
++*p;
}
int main() {
int i = 3;
p = &i;
printf("%d\n", i); // i is 3 here.
f();
printf("%d\n", i); // Huh? i is 4 here.
}
现在,当然,i
为什么在这个程序中发生了变化,这是完全而且非常明显的,但我们假设我完全忽略了它。
如果我在第13行设置断点(对f
的调用),并检查i
,我发现它仍然是3
。
Breakpoint 1, main () at test.cc:13 13 f(); (gdb) p i $1 = 3
那里不足为奇。而且我已经确定未来某个未知点的价值会发生变化,我只是不知道什么时候。
我现在可以使用watch
指令来监视变量的变量:
(gdb) watch i Hardware watchpoint 2: i
然后继续执行:
(gdb) cont Continuing. Hardware watchpoint 2: i Old value = 3 New value = 4 f () at test.cc:7 7 } (gdb) bt #0 f () at test.cc:7 #1 0x004011e9 in main () at test.cc:13
现在,我已经看到修改i
的代码就在f
的结束括号之前。
这是您需要对自己的代码执行的操作。它会比这个简单的例子复杂一点,但你也应该能够将它用于你自己的代码。