zoukankan      html  css  js  c++  java
  • 程序异常退出调试

    这周遇到一个非常奇怪的事,程序在压力测试的时候会莫名奇怪的挂掉,但是调试时却发现情况也是很诡异。使用GDB打印调用栈后发现,函数调用栈里的this指针指向的值不对劲。

     CRedisClient::connect (this=0x603, 
        ip=<error reading variable: Cannot access memory at address 0x1>, port=4, 
        timeout=-1956863078)
    

    不仅如此,所有参数的值都不对。当时就在想,是不是某个地方的操作导致内存溢出了,覆盖了栈内容,于是就想顺着调用栈一直往上找,看看是在哪个函数调用处出的问题,然而却发现找到第一个调用栈时,this指针和函数参数还是不对,更加让人不解的是,所有的调用栈里,使用info locals查看变到的局部变量的值都是正确的,这就表明,程序堆栈并没有完全被破坏掉。而且,某些局部变量的值是从函数参数里算出来的,但是info args查看参数就有问题,info locals查看局部变量就有问题。通过查找资料,大概明白了可能原因,由于现在的CPU都拥有数量较多的寄存器,于是,一般的参数传递都是使用寄存器来进行的,http://blog.csdn.net/dayancn/article/details/51328959中有介绍到:

    X86-64有16个64位寄存器,分别是:%rax,%rbx,%rcx,%rdx,%esi,%edi,%rbp,%rsp,%r8,%r9,%r10,%r11,%r12,%r13,%r14,%r15。其中:
    %rax 作为函数返回值使用。
    %rsp 栈指针寄存器,指向栈顶
    %rdi,%rsi,%rdx,%rcx,%r8,%r9 用作函数参数,依次对应第1参数,第2参数。。。
    %rbx,%rbp,%r12,%r13,%14,%15 用作数据存储,遵循被调用者使用规则,简单说就是随便用,调用子函数之前要备份它,以防他被修改
    %r10,%r11 用作数据存储,遵循调用者使用规则,简单说就是使用之前要先保存原值
    

    于是我就查看了一下rdi, rsi, rdx几个寄存器的值,果然这几个寄存器的值全都有问题,怪不得所有的参数都看不见呢,估计是在什么地方被写坏了。由于对寄存器的了解不是很深入,只好放弃core文件的调试,直接开着gdb 运行程序进行压测吧。这一开,发现

    满屏的创建新线程提示啊,查看了下进程的线程数目,3000多呢,有时候能过万。这太不正常了,不是使用线程池的吗?联想到以前20路压测时没出过问题,在100路压测时就有了问题,应该可能是跟线程数量过多有关,于是查找线程池相关的代码,果然是有问题的,

    只有增加线程,没有删除线程,怪不得线程数量会一直增加。

    然而还是没有找到程序异常退出的直接原因,但是得先将线程池这个地方的数量控制加上去再进行测试,这个问题还远没有结束,看来还得继续找下去。。。

  • 相关阅读:
    [整理]修改git 默认编辑器为vim
    [转]如何清空Chrome缓存和Cookie
    [整理]docker内部时区修改的两种方法
    [译]10个有关SCP的命令
    [译]在python中如何有效的比较两个无序的列表是否包含完全同样的元素(不是set)?
    通过设计表快速了解sql语句中字段的含义
    [整理]什么是排序算法的稳定性,为什么它很重要?
    pyinstaller打包自己的python程序
    [问题解决]ps aux中command命令相同,如何找出自己要的进程号?
    [常识]Windows系统里休眠和睡眠的区别?
  • 原文地址:https://www.cnblogs.com/yutongqing/p/6541165.html
Copyright © 2011-2022 走看看