多线程调试—原理与实践

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

背景

最近搜索在切换新搜索平台,在切换过程中发现一个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
目录
相关文章
|
1月前
|
并行计算 Java 数据处理
SpringBoot高级并发实践:自定义线程池与@Async异步调用深度解析
SpringBoot高级并发实践:自定义线程池与@Async异步调用深度解析
150 0
|
7天前
|
存储 安全 Java
Java多线程编程的艺术:从基础到实践####
本文深入探讨了Java多线程编程的核心概念、应用场景及其实现方式,旨在帮助开发者理解并掌握多线程编程的基本技能。文章首先概述了多线程的重要性和常见挑战,随后详细介绍了Java中创建和管理线程的两种主要方式:继承Thread类与实现Runnable接口。通过实例代码,本文展示了如何正确启动、运行及同步线程,以及如何处理线程间的通信与协作问题。最后,文章总结了多线程编程的最佳实践,为读者在实际项目中应用多线程技术提供了宝贵的参考。 ####
|
4天前
|
监控 安全 Java
Java中的多线程编程:从入门到实践####
本文将深入浅出地探讨Java多线程编程的核心概念、应用场景及实践技巧。不同于传统的摘要形式,本文将以一个简短的代码示例作为开篇,直接展示多线程的魅力,随后再详细解析其背后的原理与实现方式,旨在帮助读者快速理解并掌握Java多线程编程的基本技能。 ```java // 简单的多线程示例:创建两个线程,分别打印不同的消息 public class SimpleMultithreading { public static void main(String[] args) { Thread thread1 = new Thread(() -> System.out.prin
|
7天前
|
Java UED
Java中的多线程编程基础与实践
【10月更文挑战第35天】在Java的世界中,多线程是提升应用性能和响应性的利器。本文将深入浅出地介绍如何在Java中创建和管理线程,以及如何利用同步机制确保数据一致性。我们将从简单的“Hello, World!”线程示例出发,逐步探索线程池的高效使用,并讨论常见的多线程问题。无论你是Java新手还是希望深化理解,这篇文章都将为你打开多线程的大门。
|
17天前
|
缓存 Java 调度
Java中的多线程编程:从基础到实践
【10月更文挑战第24天】 本文旨在为读者提供一个关于Java多线程编程的全面指南。我们将从多线程的基本概念开始,逐步深入到Java中实现多线程的方法,包括继承Thread类、实现Runnable接口以及使用Executor框架。此外,我们还将探讨多线程编程中的常见问题和最佳实践,帮助读者在实际项目中更好地应用多线程技术。
22 3
|
19天前
|
监控 安全 Java
Java多线程编程的艺术与实践
【10月更文挑战第22天】 在现代软件开发中,多线程编程是一项不可或缺的技能。本文将深入探讨Java多线程编程的核心概念、常见问题以及最佳实践,帮助开发者掌握这一强大的工具。我们将从基础概念入手,逐步深入到高级主题,包括线程的创建与管理、同步机制、线程池的使用等。通过实际案例分析,本文旨在提供一种系统化的学习方法,使读者能够在实际项目中灵活运用多线程技术。
|
17天前
|
缓存 安全 Java
Java中的多线程编程:从基础到实践
【10月更文挑战第24天】 本文将深入探讨Java中的多线程编程,包括其基本原理、实现方式以及常见问题。我们将从简单的线程创建开始,逐步深入了解线程的生命周期、同步机制、并发工具类等高级主题。通过实际案例和代码示例,帮助读者掌握多线程编程的核心概念和技术,提高程序的性能和可靠性。
13 2
|
18天前
|
Java
Java中的多线程编程:从基础到实践
本文深入探讨Java多线程编程,首先介绍多线程的基本概念和重要性,接着详细讲解如何在Java中创建和管理线程,最后通过实例演示多线程的实际应用。文章旨在帮助读者理解多线程的核心原理,掌握基本的多线程操作,并能够在实际项目中灵活运用多线程技术。
|
23天前
|
Java API 调度
Java中的多线程编程:理解与实践
本文旨在为读者提供对Java多线程编程的深入理解,包括其基本概念、实现方式以及常见问题的解决方案。通过阅读本文,读者将能够掌握Java多线程编程的核心知识,提高自己在并发编程方面的技能。
|
29天前
|
安全 Java UED
Java中的多线程编程:从基础到实践
本文深入探讨了Java中的多线程编程,包括线程的创建、生命周期管理以及同步机制。通过实例展示了如何使用Thread类和Runnable接口来创建线程,讨论了线程安全问题及解决策略,如使用synchronized关键字和ReentrantLock类。文章还涵盖了线程间通信的方式,包括wait()、notify()和notifyAll()方法,以及如何避免死锁。此外,还介绍了高级并发工具如CountDownLatch和CyclicBarrier的使用方法。通过综合运用这些技术,可以有效提高多线程程序的性能和可靠性。