多线程调试—原理与实践

简介: 多线程调试—原理与实践

背景

最近搜索在切换新搜索平台,在切换过程中发现一个case会在检索过程中触发coredump。借助这个case详细讲述下GDB和线程调度的细节,进而更好的理解多线程调试。

正文

搜索系统收到检索请求,会将请求按照库进行任务分解,放到任务队列,线程池中的工作线程拿到任务执行检索。本次出现coredump的点就是工作线程执行的代码。

对于多线程调试就涉及到一个概念All-Stop Mode。先按下这个概念不提,如果没有设置All-Stop Mode,就进行调试,会发生什么:

(gdb) break word_element.cpp:39
Breakpoint 1 at 0x109b5dc: file word_element.cpp, line 39.
(gdb) c
Continuing.
[New Thread 0x7fca27926700 (LWP 76457)]
[New Thread 0x7fca27125700 (LWP 76458)]
[Switching to Thread 0x7fca27926700 (LWP 76457)]
Breakpoint 1, WordElement::Reset (this=0x3a5fe020, node=...) at word_element.cpp:39
39     word_element.cpp: No such file or directory.
(gdb) print node.PrintDebugString()
[Switching to Thread 0x7fca27125700 (LWP 76458)]
Breakpoint 1, WordElement::Reset (this=0x44b21420, node=...) at word_element.cpp:39
39     in word_element.cpp
The program stopped in another thread while making a function call from GDB.
(google::protobuf::Message::PrintDebugString() const) will be abandoned.
When the function is done executing, GDB will silently stop.

由于执行函数调用,当前进程因为另外一个线程执行而停止,调试进行不下去了。回到刚刚的概念

什么是“All-Stop Mode”?

GDB无法单步调试所有线程,由于线程的调度策略取决于调试的操作系统,当调试线程执行一步时,其他线程可能执行不止一条语句。当调试线程continue或者单步执行时,一旦其他线程在当前线程的执行结束之前触发断点、异常、信号,可能会发现程序终止(program stopped)。由于触发,GDB会自动切换到触发线程并提示“ [Switching to Thread n]”。因此,如果想要顺利调试需要使用“set scheduler-locking on”锁定操作系统调度器,只允许调试线程执行。

(gdb) break word_element.cpp:39
Breakpoint 1 at 0x109b5dc: word_element.cpp, line 39.
(gdb) c
Continuing.
[New Thread 0x7f42de3af700 (LWP 52695)]
[New Thread 0x7f42ddbae700 (LWP 52696)]
[Switching to Thread 0x7f42de3af700 (LWP 52695)]
Breakpoint 1, WordElement::Reset (this=0x42c76020, node=...) at word_element.cpp:39
39     word_element.cpp: No such file or directory.
(gdb) set scheduler-locking on
(gdb) print node.PrintDebugString()
node_level: 3
node_weight: 0.49673182
hit_field: 0

如上,就可以愉快的排查堆栈,查看coredump发生的原因了

本文作者 : cyningsun

本文地址https://www.cyningsun.com/10-11-2017/multithread-debug.html

版权声明 :本博客所有文章除特别声明外,均采用 CC BY-NC-ND 3.0 CN 许可协议。转载请注明出处!

相关实践学习
阿里云图数据库GDB入门与应用
图数据库(Graph Database,简称GDB)是一种支持Property Graph图模型、用于处理高度连接数据查询与存储的实时、可靠的在线数据库服务。它支持Apache TinkerPop Gremlin查询语言,可以帮您快速构建基于高度连接的数据集的应用程序。GDB非常适合社交网络、欺诈检测、推荐引擎、实时图谱、网络/IT运营这类高度互连数据集的场景。 GDB由阿里云自主研发,具备如下优势: 标准图查询语言:支持属性图,高度兼容Gremlin图查询语言。 高度优化的自研引擎:高度优化的自研图计算层和存储层,云盘多副本保障数据超高可靠,支持ACID事务。 服务高可用:支持高可用实例,节点故障迅速转移,保障业务连续性。 易运维:提供备份恢复、自动升级、监控告警、故障切换等丰富的运维功能,大幅降低运维成本。 产品主页:https://www.aliyun.com/product/gdb
目录
相关文章
|
3月前
|
并行计算 Java 数据处理
SpringBoot高级并发实践:自定义线程池与@Async异步调用深度解析
SpringBoot高级并发实践:自定义线程池与@Async异步调用深度解析
265 0
|
1月前
|
存储 监控 小程序
Java中的线程池优化实践####
本文深入探讨了Java中线程池的工作原理,分析了常见的线程池类型及其适用场景,并通过实际案例展示了如何根据应用需求进行线程池的优化配置。文章首先介绍了线程池的基本概念和核心参数,随后详细阐述了几种常见的线程池实现(如FixedThreadPool、CachedThreadPool、ScheduledThreadPool等)的特点及使用场景。接着,通过一个电商系统订单处理的实际案例,分析了线程池参数设置不当导致的性能问题,并提出了相应的优化策略。最终,总结了线程池优化的最佳实践,旨在帮助开发者更好地利用Java线程池提升应用性能和稳定性。 ####
|
2月前
|
缓存 Java 开发者
Java多线程并发编程:同步机制与实践应用
本文深入探讨Java多线程中的同步机制,分析了多线程并发带来的数据不一致等问题,详细介绍了`synchronized`关键字、`ReentrantLock`显式锁及`ReentrantReadWriteLock`读写锁的应用,结合代码示例展示了如何有效解决竞态条件,提升程序性能与稳定性。
172 6
|
2月前
|
安全 Java 开发者
Java中的多线程编程:从基础到实践
本文深入探讨了Java多线程编程的核心概念和实践技巧,旨在帮助读者理解多线程的工作原理,掌握线程的创建、管理和同步机制。通过具体示例和最佳实践,本文展示了如何在Java应用中有效地利用多线程技术,提高程序性能和响应速度。
71 1
|
2月前
|
Java 开发者
Java多线程编程的艺术与实践####
本文深入探讨了Java多线程编程的核心概念、应用场景及实践技巧。不同于传统的技术文档,本文以实战为导向,通过生动的实例和详尽的代码解析,引领读者领略多线程编程的魅力,掌握其在提升应用性能、优化资源利用方面的关键作用。无论你是Java初学者还是有一定经验的开发者,本文都将为你打开多线程编程的新视角。 ####
|
2月前
|
存储 安全 Java
Java多线程编程的艺术:从基础到实践####
本文深入探讨了Java多线程编程的核心概念、应用场景及其实现方式,旨在帮助开发者理解并掌握多线程编程的基本技能。文章首先概述了多线程的重要性和常见挑战,随后详细介绍了Java中创建和管理线程的两种主要方式:继承Thread类与实现Runnable接口。通过实例代码,本文展示了如何正确启动、运行及同步线程,以及如何处理线程间的通信与协作问题。最后,文章总结了多线程编程的最佳实践,为读者在实际项目中应用多线程技术提供了宝贵的参考。 ####
|
2月前
|
监控 安全 Java
Java中的多线程编程:从入门到实践####
本文将深入浅出地探讨Java多线程编程的核心概念、应用场景及实践技巧。不同于传统的摘要形式,本文将以一个简短的代码示例作为开篇,直接展示多线程的魅力,随后再详细解析其背后的原理与实现方式,旨在帮助读者快速理解并掌握Java多线程编程的基本技能。 ```java // 简单的多线程示例:创建两个线程,分别打印不同的消息 public class SimpleMultithreading { public static void main(String[] args) { Thread thread1 = new Thread(() -> System.out.prin
|
2月前
|
Java UED
Java中的多线程编程基础与实践
【10月更文挑战第35天】在Java的世界中,多线程是提升应用性能和响应性的利器。本文将深入浅出地介绍如何在Java中创建和管理线程,以及如何利用同步机制确保数据一致性。我们将从简单的“Hello, World!”线程示例出发,逐步探索线程池的高效使用,并讨论常见的多线程问题。无论你是Java新手还是希望深化理解,这篇文章都将为你打开多线程的大门。
|
2月前
|
缓存 Java 调度
Java中的多线程编程:从基础到实践
【10月更文挑战第24天】 本文旨在为读者提供一个关于Java多线程编程的全面指南。我们将从多线程的基本概念开始,逐步深入到Java中实现多线程的方法,包括继承Thread类、实现Runnable接口以及使用Executor框架。此外,我们还将探讨多线程编程中的常见问题和最佳实践,帮助读者在实际项目中更好地应用多线程技术。
31 3
|
2月前
|
监控 安全 Java
Java多线程编程的艺术与实践
【10月更文挑战第22天】 在现代软件开发中,多线程编程是一项不可或缺的技能。本文将深入探讨Java多线程编程的核心概念、常见问题以及最佳实践,帮助开发者掌握这一强大的工具。我们将从基础概念入手,逐步深入到高级主题,包括线程的创建与管理、同步机制、线程池的使用等。通过实际案例分析,本文旨在提供一种系统化的学习方法,使读者能够在实际项目中灵活运用多线程技术。