• 程序异常退出调试


    这周遇到一个非常奇怪的事,程序在压力测试的时候会莫名奇怪的挂掉,但是调试时却发现情况也是很诡异。使用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路压测时就有了问题,应该可能是跟线程数量过多有关,于是查找线程池相关的代码,果然是有问题的,

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

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

  • 相关阅读:
    Java应用开发与实践
    大话存储:存储系统底层架构原理极限剖析(终极版)
    Excel 2016公式与函数应用大全
    Excel高效办公应用技巧
    业务弯路池子
    一个现象,
    为什么有时候 进入这么多次,一次是 38次,一次是 114次,
    恶心 从判断开始,
    but,
    这两个的意思是不同的。。。
  • 原文地址:https://www.cnblogs.com/yutongqing/p/6541165.html
Copyright © 2020-2023  润新知