如何使用GDB步入std::map调用的派生类虚函数?
现有基类(包含纯虚函数greeting())及两个派生类,派生类各自实现了greeting()方法。通过std::map<std::string, Base*>存储对象名与对应指针,执行obj_map["..."]->greeting()调用虚函数时,使用GDB的step命令会优先进入std::map的operator[],而非直接步入派生类的greeting()实现。请问能否让GDB直接步入对应派生类的greeting()?此外项目规模庞大、编译耗时,且派生类数量超过200个,希望无需修改代码实现需求。
没问题,无需修改代码,通过GDB自带的命令技巧就能实现:
nexti+stepi组合跳转
当停在obj_map["..."]->greeting()这一行时,先执行ni(nexti的缩写)跳过std::map::operator[]的用户态代码,直接定位到虚函数调用的机器指令处,再执行si(stepi的缩写)就能直接步入目标派生类的greeting()实现。提前给
greeting()设断点
如果明确要调试的派生类,直接执行break DerivedXXX::greeting设置断点,运行到断点后自然进入目标函数。如果不确定具体是哪个派生类调用,执行break Base::greeting即可——纯虚函数的断点会命中所有派生类的实现,触发时GDB会提示当前调用的是哪个派生类的方法。用
skip命令自动跳过std::map代码
配置GDB自动跳过std::map相关的库实现,这样后续执行step时就不会进入operator[]:skip -rfu std::map skip -rfu std::map::operator[]该设置生效后,
step命令会直接跳过std::map的逻辑,直奔虚函数调用环节。
内容的提问来源于stack exchange,提问作者Dylan

