多线程+fork 引发的bug查找
1. 问题描述
某个server SA是一个多线程服务器,主线程会调用fork,再exec生成工作进程SB。
实际上,SA的主线程fork出了一个子线程,但没有执行exec。
# ps ajxf | grep r2server
14022 28342 28341 14022 pts/2 28341 S+ 0 0:00 | \_ grep r2server
1 28046 28037 3823 ? -1 Sl 0 31:25 ./r2server ../conf/r2server.conf
28046 28075 28037 3823 ? -1 S 0 0:00 \_ ./r2server ../conf/r2server.conf
2. 问题定位
2.1 用pstack观察2个进程当前stack状态。
# pstack 28075
#0 0x00007f40f24bf264 in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x00007f40f24ba508 in _L_lock_854 () from /lib64/libpthread.so.0
#2 0x00007f40f24ba3d7 in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x000000000043b407 in r2::log::LogFactory::log_printf(char const*, char const*, int, char const*, int, char const*, ...) ()
发现被lock住了。
google “pthread_mutex_lock owner”找到文献 https://en.wikibooks.org/wiki/Linux_Applications_Debugging_Techniques/Deadlocks,
安装上面的方法,定位:
f 3
(gdb) info reg
rax 0xfffffffffffffe00 -512
rbx 0x7517a0 7673760
rcx 0xffffffffffffffff -1
rdx 0x7f40d9ff86bf 139916512036543
rsi 0x80 128
rdi 0x753fb0 7684016
rbp 0x753fb0 0x753fb0
rsp 0x7f40d9ff85c0 0x7f40d9ff85c0
r8 0x753fb0 7684016
(gdb) p *(pthread_mutex_t*)0x753fb0
$1 = {__data = {__lock = 2, __count = 0, __owner = 28049,
说明当前线程的在等待一个锁,该锁被28049占有了。
# pstack 28049
Thread 1 (process 28049):
#0 0x00007f40f1a65ef3 in epoll_wait () from /lib64/libc.so.6
说明该线程已经释放了这个锁。
因此原因 是多线程+fork引起的bug:进程组28046里的主线程28046调用fork的时候,此时线程28049占用了一个锁A(正在打log),创建了子进程28075。
子进程执行exec前的代码,遇到log_printf调用,去申请锁A。因为锁A是被lock的,因此该进程死锁,执行不了到exec。
进程组28046的线程28049打完log后,释放了锁A(进程组28046和进程28075是两个不同的进程空间,有不同的page table。此时释放锁A会采用copy on write技术,创建一个新的锁A),继续正常执行。
根本原因:由于多线程的存在,某个线程占用了一个锁,因此fork的时候,fork出来的进程地址空间包含了这个被占用的锁。如果在exec之前,调用再申请这个锁,会导致死锁。
3. 解决方案
1. 多线程 or fork二选一。
2. 多线程+fork的时候,fork到exec之间只调用的async—signal function (man 7 singal),因为此时进程状态是unsafe的。
参考文献:
http://www.linuxprogrammingblog.com/threads-and-fork-think-twice-before-using-them
https://en.wikibooks.org/wiki/Linux_Applications_Debugging_Techniques/Deadlocks
多线程+fork 引发的bug查找的更多相关文章
- Spring 循环引用(一)一个循环依赖引发的 BUG
Spring 循环引用(一)一个循环依赖引发的 BUG Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) Spring 循环 ...
- 记一次PHP7+opcache+zmq出现SIGSEGV 问题的查找(一次不成功的bug查找)
Title: 记一次PHP7+opcache+zmq出现SEGSEGV问题的查找(一次不成功的bug查找) bug来历自述:线上代码PHP环境是5.2,为了提升性能(逼格),于是升级为PHP7并使用 ...
- bug 查找 (二) 从前端找到后端
bug 查找 (二) 从前端找到后端 几天来,组长说我们系统的 apm 数据不正确,最体表现就是前端项目这几天错误统计为 0. 这不正常(没有办法,我们代码写的很烂),因为前端环境很复杂,网络,浏览器 ...
- # bug 查找 (一) 快速记录 IE8 下三个问题
bug 查找 (一) 快速记录 IE8 下三个问题 昨天 pc 端网站上灰度,发现多个在 IE8 下的问题,描述和解决方案如下: 第一个问题是 css 文件过大 现象 把项目所有的 css 打包成单个 ...
- 安卓微信overflow-x overflow-y引发的bug
今天xgo文章图片页上线用微信扫页面发现一个bug,页面可以双击放大缩小. 找了半天原因,发现是图片描述设置了overflow-y引发的bug. 建议在微信场景里满屏显示不能滚动的页面里慎用overf ...
- QByteArray引发的bug
QByteArray引发的bug 在接收UDP数据的函数里,有如下代码片段 if(0x10 == data.size() && 0xCA == (unsigned char)data. ...
- 一场由fork引发的超时,让我们重新探讨了Redis的抖动问题
摘要:一次由fork引发的时延抖动问题. 背景介绍 华为云数据库GaussDB(for Redis) 是一款基于计算存储分离架构,兼容Redis生态的云原生NoSQL数据库:它依靠共享存储池实现了强一 ...
- 一个由单例模式在多线程环境下引发的 bug
问题症状 HTTP 日志系统,老是出现日志信息覆盖的情况.比如同时调用 A 接口和 B 接口,B 接口请求响应信息变成了 A 接口请求响应相关信息.这个问题在并发量大的情况下越来越严重. 问题初步分析 ...
- 一次关于使用status作为变量引发的bug及思考
这个bug出现在一年前,当时自己大学还没毕业,刚刚进入一家公司实习.那个时候还没有用seajs或者requirejs那样的模块化管理的库,也没有用一个自执行的函数将要执行的代码包裹起来,于是bug就在 ...
随机推荐
- JVM运行数据区
1.java虚拟机在运行的时候会把内存分为以下几个区域,如图:
- Ternary Search Tree 应用--搜索框智能提示
前面介绍了Ternary Search Tree和它的实现,那么可以用Ternary Search Tree来实现搜索框的只能提示,因为Ternary Search Tree的前缀匹配效率是非常高的, ...
- 让你的WizFi250适应各种气候
这篇文章会具体描写叙述如何马上得到指定城市的天气状况(比方首尔).由OpenWeatherMap提供. 用JSON(由OpenWeatherMap提供),XML和一个以太网模块.使WIZnet-Wiz ...
- C++之智能指针
导读 一直对智能指针有一种神秘的赶脚,虽然平时没怎么用上智能指针,也就看过STL中的其中一种智能指针auto_ptr,但是一直好奇智能指针的设计因此,今天看了一下<C++ Primer Plus ...
- Python开发【第八篇】:网络编程
Python之路[第六篇]:socket Socket socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字&quo ...
- 传感器 Sensor 加速度【示例】
简介 坐标系 x轴:从左到右 y轴:从下到上 z轴:从内到外 这个坐标系与Android 2D API中的不同,传感器中的返回值都以此坐标系为准. SENSOR_TYPE_ACCELEROMETER ...
- ADO.NET基础
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...
- 什么是mimeType?
因特网多媒体邮件扩展标示内容是什么格式.告诉浏览器或者server如何解析该数据http的请求和相应都含有一个mimeType字段 =>content-type(通用首部)
- Binary XML file : Error inflating class com.esri.android.map.MapView
在测试esri arcgis for android的第一个程序Helloworld的时候,报这样的错: Binary XML file : Error inflating class com.esr ...
- 【转】 iOS学习之sqlite的创建数据库,表,插入查看数据
原文: http://blog.csdn.net/totogo2010/article/details/7702207 iOS sqlite数据库操作.步骤是: 先加入sqlite开发库libsql ...