热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

GDB使用心得与技巧总结

在使用GDB进行调试时,可以采用以下技巧提升效率:1.通过设置`setprintprettyon`来美化打印输出,使数据结构更加易读;2.掌握常见数据结构的打印方法,如链表、树等;3.利用`infolocals`命令查看当前作用域内的所有局部变量;4.在需要进行类型强制转换时,正确使用语法,例如`p(Test::A*)pObj`。这些技巧能够显著提高调试的便捷性和准确性。

1.打印好看 set print pretty on

2.常用数据结构打印

3. info locals

4.如何强制转换类型,得加''

错:p *(Test::A*)pObj2 

对:p *('Test::A'*)pObj2

5.打印所有堆栈  thread apply all bt

打印堆栈到文件

set logging file /tmp/test.txt

set logging on

thread apply all bt

6.指针强转

 p ((std::_Vector_base, std::allocator > const*, std::allocator, std::allocator > const*> >*)0x7ffe310cc1a8)[0]._M_impl._M_start[0]

p value_ptr→_meta_vec._M_impl._M_start[7].proto

 p _protos._M_impl._M_start[7]

7.string条件断点

 b object_pool.h:72 if _limit_name.compare("pre_list") == 0

会报错 Unable to restore previously selected frame:

Selected thread is running.

terminate called after throwing an instance of 'gdb_exception_RETURN_MASK_ERROR'

8.predictor_serve" received signal SIGPIPE, Broken pipe.

When debugging with 'gdb', it is possible to manually disable SIGPIPE as follows:

(gdb) handle SIGPIPE nostop

7.程序卡住了

gdb attach ,其中为您的进程id。进入gdb后输入命令thread apply all bt查看进程中所有线程的状态,查看进程hang在哪了。

8.

set solib-search-path /opt/compiler/gcc-4.8.2/lib

9.当程序优化了部分变量,可以layout asm 看当前寄存器值。

10.


2. 汇编 + addr2line

对于线上core问题,一般没法再对程序进行去编译优化操作,只能在现有的core文件基础上进行代码定位,这一节我们采用一个例子来介绍如何使用汇编 + addr2line来定位代码行。

从截图可以发现frame 20指示的代码行与实际的代码行是不匹配的,这里我们采用汇编 + addr2line进行修复。


frame 20

layout asm

shell /opt/compiler/gcc-8.2/bin/addr2line -e bin address

这里直接使用了layout asm命令显示了汇编代码,命令使用传送门。最后通过addr2line命令把汇编地址转化成实际代码行。但如果想看汇编代码disassemble func_name

10. 无规律core栈

无规律core栈问题一般发生于堆内存写坏。函数调用是一个非常精密的过程,任何一个位置发生非预期的读写都会导致程序崩溃。这里可以举个小例子来说明:


1

2

3

4

5

6

int main(int argc, char* argv[]) {

    std::string s("abcd");

    *reinterpret_cast(&s) = 0x11;

     

    return 0;

}

上面的例子core在string析构上,原因是因为string的_M_ptr被改写成了0x11,析构流程变成了非法内存操作。

同理,由于进程堆空间是共享的,一个线程对堆的非法操作就可能会影响另一个线程的正常操作,由于堆分配的随机性,表现出来的现象就是无规律core栈。

针对无规律core栈最好的方式还是借助AddressSanitizer。


#设置编译参数CXXFLAGS

CXXFLAGS="-fPIC -fsanitize=address  -fno-omit-frame-pointer"

#设置链接参数

LDFLAGS="-lasan"

# 设置启动环境变量

export ASAN_OPTIONS=halt_on_error=0:abort_on_error=1:disable_coredump=0

# 启动

LD_PRELOAD=/opt/compiler/gcc-8.2/lib/libasan.so ./bin/xxx

10.函数栈修复

有时候我们会发现函数调用栈里面会出现很多??的情况,这常发生于栈被写花,某些情况下手动进行修复。函数栈的修复利用的函数栈内存分布知识,见第一节。

-----------------------------------
Low addresses
-----------------------------------
0(%rsp) | top of the stack frame | (this is the same as -n(%rbp))
---------|-------------------------
-n(%rbp) | variable sized stack frame
-8(%rbp) | varied
0(%rbp) | previous stack frame address
8(%rbp) | return address
-----------------------------------
High addresses

从上面的栈示意图可以发现,利用%rbp寄存器即可找到上一个函数的返回地址栈底指针,再利用addr2line命令找到对应的代码行。这里举一个例子:


1

2

3

4

5

6

#首先找到当前被调用栈上一个栈的栈底指针值和返回地址

/2ag $rbp # 2个单位,a=十六进制,g=8字节单元

#使用上一条命令得到的栈底指针值依次递归

/2ag address


推荐阅读
  • APKAnalyzer(1):命令行操作体验与功能解析
    在对apkChecker进行深入研究后,自然而然地关注到了Android Studio中的APK分析功能。将APK文件导入IDE中,系统会自动解析并展示其中各类文件的详细信息。官方文档提供了详细的命令行工具使用指南,帮助开发者快速上手。本文以一个RecyclerView的Adapter代理开源库为例,探讨了如何利用这些工具进行高效的APK分析。 ... [详细]
  • MongoDB Aggregates.group() 方法详解与编程实例 ... [详细]
  • 浅析Java泛型及其应用
    Java泛型是自JDK 5引入的一项重要特性,旨在增强代码的类型安全性和复用性。通过泛型,开发人员可以在编译阶段进行类型检查,有效避免运行时的类型转换错误。本文将探讨Java泛型的基本概念、实现机制及其在实际开发中的应用场景,帮助读者深入理解并灵活运用这一强大工具。 ... [详细]
  • 本文详细探讨了Java集合框架的使用方法及其性能特点。首先,通过关系图展示了集合接口之间的层次结构,如`Collection`接口作为对象集合的基础,其下分为`List`、`Set`和`Queue`等子接口。其中,`List`接口支持按插入顺序保存元素且允许重复,而`Set`接口则确保元素唯一性。此外,文章还深入分析了不同集合类在实际应用中的性能表现,为开发者选择合适的集合类型提供了参考依据。 ... [详细]
  • 本题库精选了Java核心知识点的练习题,旨在帮助学习者巩固和检验对Java理论基础的掌握。其中,选择题部分涵盖了访问控制权限等关键概念,例如,Java语言中仅允许子类或同一包内的类访问的访问权限为protected。此外,题库还包括其他重要知识点,如异常处理、多线程、集合框架等,全面覆盖Java编程的核心内容。 ... [详细]
  • 深入解析Python中的循环双向链表数据结构
    本文详细探讨了Python中循环双向链表的数据结构,包括其定义、特点及应用场景。文章首先介绍了循环双向链表的基本概念,随后深入分析了其核心操作,如节点的插入、删除和遍历等。最后,通过具体的Python代码示例,展示了如何高效地实现这些操作,帮助读者全面理解并掌握这一重要数据结构。 ... [详细]
  • 从 Java 过渡到 Ruby,不仅是一次编程语言的转换,更是一段技术进阶的旅程。本文将深入探讨两种语言在语法、生态系统和开发模式上的差异,帮助开发者顺利实现转型,并在新的环境中高效地编写高质量代码。 ... [详细]
  • voc生成xml 代码
    目录 lxmlwindows安装 读取示例 可视化 生成示例 上面是代码,下面有调用示例 api调用代码,其实只有几行:这个生成代码也很简 ... [详细]
  • 深入理解Spark框架:RDD核心概念与操作详解
    RDD是Spark框架的核心计算模型,全称为弹性分布式数据集(Resilient Distributed Dataset)。本文详细解析了RDD的基本概念、特性及其在Spark中的关键操作,包括创建、转换和行动操作等,帮助读者深入理解Spark的工作原理和优化策略。通过具体示例和代码片段,进一步阐述了如何高效利用RDD进行大数据处理。 ... [详细]
  • Android ListView 自定义 CheckBox 实现列表项多选功能详解
    本文详细介绍了在Android开发中如何在ListView的每一行添加CheckBox,以实现列表项的多选功能。用户不仅可以通过点击复选框来选择项目,还可以通过点击列表的任意一行来完成选中操作,提升了用户体验和操作便捷性。同时,文章还探讨了相关的事件处理机制和布局优化技巧,帮助开发者更好地实现这一功能。 ... [详细]
  • 深入解析十大经典排序算法:动画演示、原理分析与代码实现
    本文深入探讨了十种经典的排序算法,不仅通过动画直观展示了每种算法的运行过程,还详细解析了其背后的原理与机制,并提供了相应的代码实现,帮助读者全面理解和掌握这些算法的核心要点。 ... [详细]
  • 本文探讨了在PowerShell中高效管理和操作大规模内存对象的技术与实践。详细介绍了如何启用PowerShell的大内存支持功能,并提供了优化性能和减少资源消耗的具体方法。此外,还讨论了常见问题及其解决方案,旨在帮助用户在处理复杂数据集时提高效率和稳定性。 ... [详细]
  • 在启用分层编译的情况下,即时编译器(JIT)的触发条件涉及多个因素,包括方法调用频率、代码复杂度和运行时性能数据。本文将详细解析这些条件,并探讨分层编译如何优化JVM的执行效率。 ... [详细]
  • 在Windows命令行中,通过Conda工具可以高效地管理和操作虚拟环境。具体步骤包括:1. 列出现有虚拟环境:`conda env list`;2. 创建新虚拟环境:`conda create --name 环境名`;3. 删除虚拟环境:`conda env remove --name 环境名`。这些命令不仅简化了环境管理流程,还提高了开发效率。此外,Conda还支持环境文件导出和导入,方便在不同机器间迁移配置。 ... [详细]
  • 深入RTOS实践,面对原子操作提问竟感困惑
    在实时操作系统(RTOS)的实践中,尽管已经积累了丰富的经验,但在面对原子操作的具体问题时,仍感到困惑。本文将深入探讨RTOS中的原子操作机制,分析其在多任务环境下的重要性和实现方式,并结合实际案例解析常见的问题及解决方案,帮助读者更好地理解和应用这一关键技术。 ... [详细]
author-avatar
手机用户2502910101
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有