执行期间的变量变化。 C ++

时间:2017-09-06 09:40:23

标签: c++ gdb openmp

程序崩溃时出现分段错误,所以我用gdb运行它。我发现在运行时期间会覆盖一个类的成员。几个事实:

  • 该类未被覆盖的函数中使用。
  • 被覆盖的代码段位于omp临界区。

我检查了调试器停止的行 - 此行中访问的变量具有不同的内存地址。

一段gdb代码:

(gdb) p SrcVelField
$1 = (SNGM::FieldVector *) 0x555555a237a0
(gdb) p *SrcVelField
$2 = {MeshRef = 0x55555592e530, Values = {data_ = 0x555555a237f0}, NbVar = 3, 
  NbVal = 8820, VarName = {data_ = 0x55555592f000}, 
  FieldName = "VelocityField"}
(gdb) p (*SrcVelField).NbVar
$3 = 3
(gdb) p &(*SrcVelField).NbVar
$4 = (unsigned int *) 0x555555a237b0
(gdb) watch -l *0x555555a237b0
Hardware watchpoint 2: -location *0x555555a237b0
(gdb) cont
Thread 1 "SNGM" hit Hardware watchpoint 2: -location *0x555555a237b0

Old value = 3
New value = -118991381
SNGM::GlobalEval<SNGM::FilterGaussian, 3u, 1u>::PerformGlobalEval ()
at ../SNGM/Numerics/GlobalEval.cpp:288
288   for (unsigned ii =     0; ii < nx; ii++){
(gdb) p &ii
$5 = (unsigned int *) 0x7fffffffc93c
(gdb) p &nx
$6 = (const unsigned int *) 0x7fffffffc950

我很高兴提示为什么(*SrcVelField).NbVar的价值正在改变。

更新 在这一行中反汇编代码会产生下一个: - 有问题的rax值

(gdb) info registers
rax            0x555555a237b0   93824997275568
rbx            0x61a8   25000

及其指示

280                                     delete[] point;
0x0000555555595bcc <+1113>:  cmpq   $0x0,-0x58(%rbp)
0x0000555555595bd1 <+1118>:  je     0x555555595adc 

<PerformGlobalEvalEv._omp_fn.0(void)+873>
0x0000555555595bd7 <+1124>:  mov    -0x58(%rbp),%rax
0x0000555555595bdb <+1128>:  mov    %rax,%rdi
0x0000555555595bde <+1131>:  callq  0x555555564758
0x0000555555595be3 <+1136>:  jmpq   0x555555595adc 
<PerformGlobalEvalEv._omp_fn.0(void)+873>

281                             } //End for all particles
282
283     #pragma omp critical
   0x0000555555595f5b <+2024>:  callq  0x555555564ae8
   0x0000555555595f78 <+2053>:  callq  0x555555564a40

284                             {
285
286                                     for (unsigned kk = 0; kk < nz; kk++){
   0x0000555555595f60 <+2029>:  movl   $0x0,-0x15c(%rbp)
   0x0000555555595f6a <+2039>:  mov    -0x15c(%rbp),%eax
   0x0000555555595f70 <+2045>:  cmp    -0x148(%rbp),%eax
   0x0000555555595f76 <+2051>:  jb     0x555555595fed 



<PerformGlobalEvalEv._omp_fn.0(void)+2170>
   0x0000555555596005 <+2194>:  addl   $0x1,-0x15c(%rbp)
   0x000055555559600c <+2201>:  jmpq   0x555555595f6a 
<PerformGlobalEvalEv._omp_fn.0(void)+2039>

287                                             for (unsigned jj = 0; jj < ny; jj++){
   0x0000555555595fed <+2170>:  movl   $0x0,-0x158(%rbp)
   0x0000555555595ff7 <+2180>:  mov    -0x158(%rbp),%eax
   0x0000555555595ffd <+2186>:  cmp    -0x144(%rbp),%eax
   0x0000555555596003 <+2192>:  jb     0x555555596011 
<PerformGlobalEvalEv._omp_fn.0(void)+2206>
   0x0000555555596029 <+2230>:  addl   $0x1,-0x158(%rbp)
   0x0000555555596030 <+2237>:  jmp    0x555555595ff7 
<PerformGlobalEvalEv._omp_fn.0(void)+2180>

288                                                     for (unsigned ii = 0; ii < nx; ii++){
   0x0000555555596011 <+2206>:  movl   $0x0,-0x154(%rbp)
   0x000055555559601b <+2216>:  mov    -0x154(%rbp),%eax
   0x0000555555596021 <+2222>:  cmp    -0x140(%rbp),%eax
   0x0000555555596027 <+2228>:  jb     0x555555596032 
<PerformGlobalEvalEv._omp_fn.0(void)+2239>
=> 0x0000555555596177 <+2564>:  addl   $0x1,-0x154(%rbp)

1 个答案:

答案 0 :(得分:2)

当堆栈/堆大小耗尽或数组索引超出范围时,这是常见的行为。检查堆栈和堆大小,并确认您没有超出它们。然后检查所有数组/列表实例,并验证它们是否受到保护以防止越界错误。