针对gdb出现DWARF错误的问题

针对gdb出现DWARF错误的问题:在build文件夹中运行:添加环境变量

export CXXFLAGS="-g -gdwarf-4"
export CFLAGS="-g -gdwarf-4"

然后清空build文件夹,重新编译,就OK了。


debug时,出现下面的情况,如何查看数值:

(gdb) p coords0                                                                       
$1 = (petibm::type::RealVec2D &) @0x5555565abf70: {<std::_Vector_base<std::vector<dou\
ble, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<doub\
le> > > >> = {_M_impl = {<std::allocator<std::vector<double, std::allocator<double> >\
 >> = {<std::__new_allocator<std::vector<double, std::allocator<double> > >> = {<No d\
ata fields>}, <No data fields>}, <std::_Vector_base<std::vector<double, std::allocato\
r<double> >, std::allocator<std::vector<double, std::allocator<double> > > >::_Vector\
_impl_data> = {_M_start = 0x5555565ac060, _M_finish = 0x5555565acbb8, _M_end_of_stora\
ge = 0x5555565acbb8}, <No data fields>}}, <No data fields>}                           

先启用GDB的打印自动排版

(gdb) set print pretty on 

就会变成:

(gdb) p coords                                                                        
$3 = (petibm::type::RealVec2D &) @0x5555565ac0e8: {                                   
  <std::_Vector_base<std::vector<double, std::allocator<double> >, std::allocator<std\
::vector<double, std::allocator<double> > > >> = {                                    
    _M_impl = {                                                                       
      <std::allocator<std::vector<double, std::allocator<double> > >> = {             
        <std::__new_allocator<std::vector<double, std::allocator<double> > >> = {<No \
data fields>}, <No data fields>},                                                     
      <std::_Vector_base<std::vector<double, std::allocator<double> >, std::allocator\
<std::vector<double, std::allocator<double> > > >::_Vector_impl_data> = {             
        _M_start = 0x5555565ae270,                                                    
        _M_finish = 0x5555565aedc8,                                                   
        _M_end_of_storage = 0x5555565aedc8                                            
      }, <No data fields>}                                                            
  }, <No data fields>}                                                                

如果不希望每次启动 GDB 都要手动输入,可以创建配置文件:

# 在家目录创建 .gdbinit 文件
echo "set print pretty on" >> ~/.gdbinit
echo "set print array on" >> ~/.gdbinit
echo "set print object on" >> ~/.gdbinit

举一个例子:

查看coords[0][0]的命令:

(gdb) p coords._M_impl._M_start[0]._M_impl._M_start[0]
$4 = 0.5990000065797233                               

再举一个例子:

查看body 的类型:

(gdb) p body                                                                          
$2 = (petibm::type::SingleBody &) @0x5555565abe70: {                                  
  <std::__shared_ptr<petibm::body::SingleBodyBase, (__gnu_cxx::_Lock_policy)2>> = {   
    <std::__shared_ptr_access<petibm::body::SingleBodyBase, (__gnu_cxx::_Lock_policy)\
2, false, false>> = {<No data fields>},                                               
    members of std::__shared_ptr<petibm::body::SingleBodyBase, (__gnu_cxx::_Lock_poli\
cy)2>:                                                                                
    _M_ptr = 0x5555565abee0,                                                          
    _M_refcount = {                                                                   
      _M_pi = 0x5555565abed0                                                          
    }                                                                                 
  }, <No data fields>}                                                                

查看body里面的成员变量nPts

(gdb) p body._M_ptr->nPts   
$3 = 121                    

为什么访问路径不同?

你可能会好奇:为什么访问 coords[0][0] 需要 coords._M_impl._M_start[0]._M_impl._M_start[0] 这么复杂的路径,而访问 body 的成员只需要 body._M_ptr->nPts

1. coords 的类型结构

coords 的类型是 petibm::type::RealVec2D,从 GDB 输出可以看出它继承自:

  • std::_Vector_base<std::vector<double>, ...> → 这是一个二维向量
  • 内部包含 _M_impl(实现对象)
  • _M_impl 包含 _M_start(指向第一个元素的指针)

所以访问路径是:

coords → _M_impl → _M_start[0] → 第一个一维向量
第一个一维向量 → _M_impl → _M_start[0] → 第一个 double 值

2. body 的类型结构

body 的类型是 petibm::type::SingleBody,从 GDB 输出可以看出:

  • 它继承自 std::__shared_ptr<petibm::body::SingleBodyBase>
  • _M_ptr 是共享指针的原始指针成员
  • nPtsSingleBodyBase 类的公有成员变量

所以访问路径是:

body → _M_ptr → nPts

3. 关键区别

特性coords (二维向量)body (共享指针)
类型std::vector<std::vector<double>>std::shared_ptr<SingleBodyBase>
访问方式通过迭代器/指针访问元素通过指针访问对象成员
GDB 路径需要深入到内部实现只需要解引用指针
C++ 代码等价coords[0][0]body->nPts

4. 为什么 GDB 需要这么长的路径?

因为 GDB 在调试时:

  1. 不能直接调用运算符重载coords[0][0] 在 C++ 代码中是 operator[] 的调用,但 GDB 不能直接调用这个运算符
  2. 需要直接访问内存布局:GDB 必须按照实际的内存结构来访问数据
  3. std::vector 的实现细节std::vector 内部使用 _M_start_M_finish_M_end_of_storage 三个指针来管理内存

5. 简化访问的方法

如果你觉得路径太长,可以定义 GDB 便利函数:

# 定义查看二维向量元素的函数
(gdb) define pvec2d
>p $arg0._M_impl._M_start[$arg1]._M_impl._M_start[$arg2]
>end

# 使用
(gdb) pvec2d coords 0 0
$5 = 0.5990000065797233

或者使用类型转换(如果知道具体类型):

(gdb) p ((std::vector<std::vector<double>>*)&coords)->at(0).at(0)

总结

  • 在于它们在内存中呈现的空间拓扑结构完全不同!

  • coords 是二维 std::vector,需要访问两次内部迭代器才能到达元素

  • bodyshared_ptr,只需要一次解引用就能访问对象成员

  • GDB 不能直接调用 operator[],所以需要手动展开内存结构

  • 这是 C++ STL 容器在调试时的常见情况,理解容器内部结构有助于高效调试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十子木

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值