【问题标题】:Strange crash, analyzing in gdb奇怪的崩溃,在gdb中分析
【发布时间】:2012-04-11 13:31:12
【问题描述】:

我有一个应用程序,我正在分析这个软件的内存故障转储。

struct GPS_CONNECTION
{
    int sockfd;
    std::string sendbuf, recvbuf;
    struct sockaddr_in remoteaddr;
};
vector <GPS_CONNECTION> GPSC;

--------------------------------
(cut)
--------------------------------

fd_set master, gps_master, read_fds, gps_read_fds, write_fds, gps_write_fds;

for (;;)
{
    /* Clear */
    FD_ZERO(&gps_read_fds);
    FD_ZERO(&gps_write_fds);

    /* read_fds */
    gps_read_fds = gps_master;

    /* write_fds */
    for (int i=0; i < GPSC.size(); i++)
    {
        if (GPSC[i].sendbuf.empty())
        {
            continue;
        }
        FD_SET(GPSC[i].sockfd, &gps_write_fds);
    }

    /* Timeout struct */
    tv.tv_sec = 0;
    tv.tv_usec = 0;

    /* selectuj write */
    if (select(gps_fdmax+1, &gps_read_fds, &gps_write_fds, NULL, &tv) == -1)
    {
        perror("select");
        return 7;
    }

    --------------------------------
    (cut)
    --------------------------------
}

GDB 崩溃转储显示软件已崩溃:

443                 if (GPSC[i].sendbuf.empty())

当我分析变量时,我看到了这个:

(gdb) print i
$1 = -1214807923

我不明白这个值是如何被覆盖的?我在这里没有看到任何堆栈溢出问题,谁能解释这次崩溃的原因?

此问题反复出现 - 两天一次,这是一个 24/7/365 工作的服务器。


在 g++ 扩展此代码后,结果:

 for (int i=0; i < GPSC.size(); i++)
 {
     if (GPSC[i].sendbuf.empty())
     {
         continue;
     }
     __asm__ __volatile__ ("btsl %1,%0" : "=m" (((&gps_write_fds)->fds_bits)[((GPSC[i].sockfd) / (8 * sizeof (__fd_mask)))]) : "r" (((int) (GPSC[i].sockfd)) % (8 * sizeof (__fd_mask))) : "cc","memory");
 }

【问题讨论】:

  • GPSC 包含什么?它是什么类型的结构?
  • GPSC 的通常尺寸是多少?这个问题是重复出现的,还是一次性的?
  • 可能溢出? vector.size() 在您使用有符号整数时返回一个无符号数。
  • 一种随机的可能性是gps_write_fds 的大小错误,结果iFD_SET 破坏了?
  • 好主意 - Svisstack,你能在 for 循环之前显示更多代码吗?具体而言,正如欧内斯特所建议的那样,gps_write_fds 变量。

标签: c++ crash crash-reports crash-dumps


【解决方案1】:

从你分享的小代码sn-p,很难说到底是什么问题。

我只能怀疑GPSC.size() 的结果大于int 可以存储的结果,因此在一些 次迭代后导致i 溢出。

【讨论】:

  • 在这个向量中放置了一个连接,在 for debug 中建议这是一个向量,因为在调试时会出现一些第二个连接。
  • @Svisstack "可能出现第二个连接"---这表明线程。如果另一个线程可以修改GPSC,那么你必须保护对它的所有访问。
  • @JamesKanze:这是一个线程循环,我在想,但只有一个线程在工作,这是一个主进程,所有套接字通信代码都使用非阻塞使用的 select 放置在这个线程中,当 next连接出现然后在选择连接被创建并放置在这个向量上。这是不可能在同一时间用同一线程执行此代码的。
【解决方案2】:

由于我之前不会考虑的多线程,代码会崩溃,我认为这仅在一个线程中工作,我的错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-12
    • 1970-01-01
    • 2013-11-16
    • 2019-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多