MacOS下LLDB调试C++如何正确转换std::shared_ptr智能指针
错误原因分析
- 你写的
std::static_pointer_cast模板参数错误:static_pointer_cast的模板参数是目标指向的类型,不需要包裹std::shared_ptr,正确写法应该是std::static_pointer_cast<Pkt2>(ptr),你写的std::static_pointer_cast<std::shared_ptr<Pkt1>>本身语法错误。 - LLDB找不到
std::static_pointer_cast是因为MacOS自带的libc++默认不会把未显式调用的模板函数实例纳入调试符号,所以调试时无法直接调用这个模板函数。 - 直接转换报错是因为不能把
std::shared_ptr对象直接强转为裸指针,需要先调用get()方法获取内部存储的裸指针再转换。 - 额外逻辑错误:
pkt2Var是Pkt2类的成员,你强转为Pkt1指针后访问该成员本身就是非法操作,即使转换成功也会读到非法内存,大概率就是你遇到段错误的原因。
正确转换方法
方法1:直接转换裸指针(最通用,LLDB下100%可用)
先调用shared_ptr的get()方法拿到基类裸指针,再强制转换为目标子类指针即可,命令如下:
p ((Pkt2*)pkts.front().get())->pkt2Var
方法2:修正static_pointer_cast用法(仅当编译时保留了模板实例可用)
如果你编译程序时开启了-O0参数、并且加了-fkeep-inline-functions参数保留了所有模板函数实例,修正模板参数后可以直接用标准库的转换函数:
p std::static_pointer_cast<Pkt2>(pkts.front())->pkt2Var
关于你怀疑的getPkts函数问题
你提供的getPkts实现逻辑本身没有问题:先拷贝队列到临时变量、清空原队列、返回拷贝后的队列,不会触发内存错误,你遇到的段错误基本可以确定是错误的子类指针转换导致的非法内存访问。
内容的提问来源于stack exchange,提问作者jkang
相关产品推荐
相关产品推荐

