由于设计到的问题比较复杂,我把问题的几个特征描述下:1,错误出现在一个线程里面。2,如果不创建线程,而是在主线程里面执行该线程的代码,完全没有问题。3,线程中包含一条调用语句,如果在调试状态下,执行到该语句的时候,跳入,然后单步执行,经不会发生错误。但如果不跳入,而是直接运行跳过该句,就会报错,错误:debug assertion failed!

解决方案 »

  1.   

    看看那个是什么断言错误,看一下call stack的调用顺序
    =========================
    搞不定就贴代码
      

  2.   

    报assertion错误,在程序整体运行,线程中用到的一些资源可能还没有被创建。
      

  3.   

    我是楼主,该程序的基本代码如下:线程创建代码:
            driver_M4.SetConnectParam("192.168.0.8",8080);
    if(!driver_M4.Connect())
    {
    MessageBox("连接设备失败","盘点",MB_OK);
    } CreateThread(NULL,0,VIPProc,this->m_hWnd,0,NULL);
    线程函数代码:DWORD WINAPI VIPProc(LPVOID paraMeter)
    {
    while(true)
    {
    driver_M4.SetReadTagIDParam(0,"SELECT id FROM tag_id;");
    if(driver_M4.ReadTagID())
    {
    MessageBeep(-1);
    }
    else
    {
    ::MessageBox((HWND)paraMeter,"读取失败","VIP",MB_OK);
    }
    } return 0;
    }
    错误就出在driver_M4.ReadTagID()这句上面,如果跳入这句,单步执行,没有问题,如果直接执行这句,就会报错。driver_M4.ReadTagID()的代码如下:
    bool DriverMagic::ReadTagID()
    {
    /* 函数代码区开始 */
    if(!isOpen)
    {
    iReturnValue = 7;
    return false;
    }
    if(s.SendTo(czSQLCommend,sizeof(czSQLCommend),iPort,czIP) == SOCKET_ERROR )
    {
    iReturnValue = 8;
    return false;
    }
    CString addr;
    unsigned int port;
    if(s.ReceiveFrom(czFreeBuffer,sizeof(czFreeBuffer),addr,port) == SOCKET_ERROR )
    {
    iReturnValue = 8;
    return false;
    }
    if(isError(czFreeBuffer))
    {
    iReturnValue = 9;
    for(int i=0;!(czFreeBuffer[i] == '\n');i++)
    ;
    strcpy(czError,czFreeBuffer);
    return false;
    }
    ChangePrivateToPublic(1,czFreeBuffer);
    return true;
    /* 函数代码区结束 */
    }
      

  4.   

    看看你ChangePrivateToPublic里面做了些什么?
      

  5.   

    出错的时候选择“重试”、“中断”,看看停在哪,再从调用堆栈中找出是自己的哪行代码引起的。
    其它线程同时在执行什么?有没有访问driver_M4?
      

  6.   

    void DriverMagic::ChangePrivateToPublic(int type,char buffer[])
    {
    /* 参数定义区开始 */
    int i = 0,j,count = 0;
    /* 参数定义区结束 */
    /* 函数代码区开始 */
    switch(type)
    {
    case 1: i = 0,count = 0;
    if((strlen(buffer) == 0)||(buffer[0] == '\n')||(buffer[1] == '\n'))
    {
    sTagID.iNumber = 0;
    return;
    }
    while(1)
    { while(!((buffer[i] == '0')&&(buffer[i+1] == 'x'||buffer[i+1] == 'X')))//寻找"0x"
    ++i;
    i += 2;
    for(j = 0;j < 16;j++,i++)
    sTagID.czTid[count][j] = buffer[i];
    sTagID.czTid[count][j] = '\0';
    ++count;
    while(!(buffer[i] == '\n'))
    ++i;
    if(buffer[i+1] == '\n')
    break; }
    sTagID.iNumber = count;
    break;
    case 2: break;
    default:break;
    }
    /* 函数代码区结束 */
    }====================很重要的一点是,我单步执行是可以用的,整体执行不能用。
      

  7.   

    打开call stack窗口
    跟进看看到底是什么断言错误
      

  8.   


    断言的截图。是ReceiveFrom报错
      

  9.   

    ReceiveFrom没用阻塞式的吧?如果当前数据缓冲区没数据用RecieveFrom会出错的,如果是阻塞式就不会有这个问题,它会阻塞在ReceiveFrom函数,直到有数据发过来.
      

  10.   

    至少要定位是哪句assert出问题吧.
      

  11.   

    应该是线程同步的问题,我把线程里面的driver_M4改成局部变量后,就没问题了。
      

  12.   

    你不是说其它线程没有用到driver_M4吗?如果是这样就与线程同步没有关系,可能是内存越界破坏了driver_M4中的数据。
      

  13.   

    是的,
    driver_M4本来是一个全局变量,
    只在创建进程前用过:
    driver_M4.SetConnectParam("192.168.0.8",8080);
        if(!driver_M4.Connect())
        {
            MessageBox("连接设备失败","盘点",MB_OK);
        }    CreateThread(NULL,0,VIPProc,this->m_hWnd,0,NULL);
      

  14.   

    driver_M4.Connect中执行了哪些操作?也有可能是某些操作需要一段时间后才能完成,而你在线程中没有等待前面的操作完成,就继续执行了后面的操作。
      

  15.   

    发送和接受处理的太简单了。可靠的方式是发送前要检测是否可以发送;接受前要检测是否可以接收。 当然这样子处理起来要麻烦很多,但是你得考虑到网络层的感受,他有很多事要做,也可能很慢,也可能对方根本就不通,不能按照你一厢情愿的想法稀里哗啦的一路下来,发了立刻就收。简单的测试和改进, 发送和接受间插入 Sleep。具体sleep时间可以多测几组。