一个DBA同事昨天在执行一个命令行工具的时候发现程序hang住,问题挺有意思,值得记录下。

  首先用pstack看了下程序的调用栈,这是个多线程程序,pstack结果看到几乎所有的线程都等在write调用上。如下是pt-pmp的输出结果:

  1. Tue May :: CST
  2. __lll_lock_wait_private,_L_lock_51,fwrite,LoadConsumer::run,CThread::hook,start_thread,clone
  3. write,_IO_new_file_write,_IO_new_file_xsputn,buffered_vfprintf,vfprintf,fprintf,LoadManager::dump,LoadProducer::load_file,LoadProducer::run,CThread::hook,start_thread,clone

  直觉上觉得是磁盘空间满了,让他看了下,磁盘空间还很富裕,touch创建文件也没任何问题,当时此机器上还在跑一个备份程序,IO压力不小,不过和问题本身应该关系不大。Google了下__lll_lock_wait_private这个错误,也没任何有用的信息。这个工具程序本身会向一个命令行指定的日志文件输出很多程序执行结果,同时会向stderr输出程序的执行状态,gdb attach看了下程序具体的调用栈,发现程序都阻塞在fprintf(stderr)上。咨询了下同事,他使用这个工具是通过一个python脚本调用的,调用的程序类似如下:

  1. p = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,close_fds=True)

  cmd是调用程序的命令行,包括一系列选项。问题看起来很清晰了,通过python调用此命令行工具时,stdout和stderr都被重定向了subprocess.PIPE,但没有程序从此PIPE读取,那么很快这个PIPE自身的buffer都写满了,pstack看到的结果就是所有write都阻塞。

  

  写了个小程序重现了下,程序如下(随手写的..): 

  1. #include <stdio.h>
  2. #include <pthread.h>
  3. #include <unistd.h>
  4. void *thr_fn(void *arg)
  5. {
  6. int i =;
  7. while(true)
  8. {
  9. i++;
  10. fprintf(stderr, "helloworld %d\t\t\t\t",i);
  11. fprintf(stdout, "kkkkkkkkkk %d\t\t\t\t",i);
  12. sleep();
  13. }
  14. }
  15.  
  16. int main(void)
  17. {
  18. for (int i = ; i!= ; i++)
  19. {
  20. pthread_t tid;
  21. pthread_create(&tid, NULL, thr_fn, NULL);
  22. }
  23.  
  24. sleep();
  25. }

  调用的python脚本如下:

  1. 1 import subprocess
  2. 2 import os
  3. 3 import time
  4. 4
  5. 5 ret = {}
  6. 6
  7. 7 cmd = "./a.out >/tmp/log"
  8. 8
  9. 9 p = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,close_fds=True)
  10. 10
  11. 11 ret['status'] = p.wait()
  12. 12 ret['msg'] = p.stdout.readlines()
  13. 13
  14. 14 time.sleep(100000000);

  执行此python脚本,会发现很快a.out就被hang住了,表现是/tmp/log不再有新的输出,程序调用栈如下:

  1. __lll_lock_wait_private,_L_lock_12956,buffered_vfprintf,vfprintf,fprintf,thr_fn,start_thread,clone
  2. write,_IO_new_file_write,_IO_new_file_xsputn,buffered_vfprintf,vfprintf,fprintf,thr_fn,start_thread,clone
  3. nanosleep,sleep,main

  

  解决此问题,1)maybe subprocess.Popen这个程序参数可以改改?2)或者在cmd里边将stdout/stderr都重定向掉;3)写命令行程序的时候要注意,调用的脚本各种写法都可能有,因此写日志尽量还是要规范,不要向stdout/stderr输出过多的东西。

  

  组里开发的同事补充了下MySQL遇到__lll_lock_wait_private 错误的常见场景:

  "这个函数调用在mysql上最典型的场景就是开启cgroup时会经常碰到这个,例如memcpy, mem alloc, free , mutext lock/unlock...."

记录一个__lll_lock_wait_private错误的更多相关文章

  1. 记录一个bootstrap惨痛的错误

    记录一个bootstrap的错误,这个错误因为我删除了一个class就导致了页面上显示的错误,这是一个惨痛的教训,特此记录,提醒自己在做前端的修改时,一定要慎之又慎.如果真的要做改动,改完之后也要测一 ...

  2. 记录一个glibc 导致的段错误以及gdb 移植

    上一篇我有相关关于一个段错误的记录,现在记录当时的段错误具体是在哪里的. // 从 GNU 的官网下载当前在使用的 glibc 的源代码以及最新的 glibc 源代码 // 地址如下: http:// ...

  3. Win10 EPLAN新建项目出现“一个内部错误的解决方法”

    [环境] Win10 64bits,EPLAN 2.4 64bits. [表现] 新建项目的时候出现"一个内部错误"的提示,然后软件卡死. [解决方案] 计算机管理--服务--EP ...

  4. 简明Python中的一个小错误

    最近在学Python,先看的是<Python基础教程>,后来经别人推荐,感觉网络上的<简明Python教程>也挺好的,在里面发现一个小错误. 网址如下:http://sebug ...

  5. 未指定的错误,发生了一个 Oracle 错误,但无法从 Oracle 中检索错误信息。数据类型不被支持。

    未指定的错误,发生了一个 Oracle 错误,但无法从 Oracle 中检索错误信息.数据类型不被支持. 博客分类: 雅芳生涯 .Net VB C# OracleMicrosoftSecurity  ...

  6. android:Faild to install,你的主机中的软件终止了一个连接错误解决

    当在用真机调试android程序时出现Faild to install,你的主机中的软件终止了一个连接错误时可以这样解决: 在手机开启usb调试和安装未知来源软件的情况下: 1:先查进入任务管理器查看 ...

  7. 11gR2RAC环境DBCA创建一个数据库错误ORA-15055 ORA-15001

    11gR2RAC环境DBCA创建一个数据库错误ORA-15055 ORA-15001 象: 在11gR2 GridInfrastructure和Database软件安装完毕之后,运行DBCA创建数据库 ...

  8. L2TP连接尝试失败,因为安全层在初始化与远程计算机的协商时遇到了一个处理错误(转)

    L2TP连接尝试失败,因为安全层在初始化与远程计算机的协商时遇到了一个处理错误   错误描述:“ L2TP连接尝试失败,因为安全层在初始化与远程计算机的协商时遇到了一个处理错误” 只有这个没有错误码. ...

  9. step_by_step_记录一个javascript字符串处理问题

    记录一个javascript字符串处理的问题 这一天下班,技术QQ群里的大神提出了一个问题,带着问题去思考. ? '---9890.999008-555555-55555555----' 对于这样的字 ...

随机推荐

  1. Android开发学习总结——Android开发的一些相关概念

    一.什么是3G.4G 1995年问世的第一代模拟制式手机(1G)只能进行语音通话. 1996到1997年出现的第二代GSM.CDMA等数字制式手机(2G)便增加了接收数据的功能 Ÿ 3G指的是第三代移 ...

  2. 字符串匹配算法之BF(Brute-Force)算法

    BF(Brute-Force)算法 蛮力搜索,比较简单的一种字符串匹配算法,在处理简单的数据时候就可以用这种算法,完全匹配,就是速度慢啊. 基本思想 从目标串s 的第一个字符起和模式串t的第一个字符进 ...

  3. crontab定时任务配置记录

    一.前言 今天简单记录下crontab的配置 二.crontab目录 /etc/crontab 文件 这是系统运行的调度任务 /var/spool/cron 目录 用户自定义的crontab任务放在此 ...

  4. 使用ConditionalScope进行高效的SharePoint CSOM编程

    在上一篇文章中讲述了 ExceptionHandlingScope的使用后,本章主要讲述ConditionalScope的用法. ConditionalScope在设计思路和解决问题上同Excepti ...

  5. C语言实现快速排序

    我觉得冒泡排序是比较简单的: 所以今天我们实现一个叫做快速排序的: Problem 你想要将(4,3,5,1,2)排序成(1,2,3,4,5) 你决定使用最简单的快速排序: Solution 首先,打 ...

  6. paip.输出内容替换在Apache 过滤器filter的设置

    paip.输出内容替换在Apache 过滤器filter的设置 作者Attilax  艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog ...

  7. C#:Oracle数据库带参PLSQL语句的正确性验证

    在有Oracle数据库C#项目中,有一个这样的需求:在界面上配置了带参数的PLSQL语句,但是要通过程序验证其正确性,那么该如何实现?这就是本文要探讨的内容. 一:通过OracleCommand对象的 ...

  8. Delphi的VCL组件库

    Visual Component Library的缩写(可视组件库)VCL是Visual Component Library的缩写,即可视组件库,它是Delphi,C++Builder等编程语言的基本 ...

  9. 《精通移动app测试实战:技术、工具和案例》新书上市

    本书是测试专家.性能测试专家.专业畅销书作者--于涌,多年实战经验的总结,涵盖主流的测试工具,包括众多的测试实例,涵盖单元测试.功能测试.性能测试.UI测试.手游测试.自动化测试.测试用例管理.持续集 ...

  10. android retrofit @Query用法

    http://www.b3a4a.com/?id=71 //https://login.xx.cn/mobile/login?access_token=A7E3D8CC98776F7C16F328B6 ...