线程中,单步调试可以顺利执行,但程序整体运行经会报错。 由于设计到的问题比较复杂,我把问题的几个特征描述下:1,错误出现在一个线程里面。2,如果不创建线程,而是在主线程里面执行该线程的代码,完全没有问题。3,线程中包含一条调用语句,如果在调试状态下,执行到该语句的时候,跳入,然后单步执行,经不会发生错误。但如果不跳入,而是直接运行跳过该句,就会报错,错误:debug assertion failed! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 看看那个是什么断言错误,看一下call stack的调用顺序=========================搞不定就贴代码 报assertion错误,在程序整体运行,线程中用到的一些资源可能还没有被创建。 我是楼主,该程序的基本代码如下:线程创建代码: 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; /* 函数代码区结束 */} 看看你ChangePrivateToPublic里面做了些什么? 出错的时候选择“重试”、“中断”,看看停在哪,再从调用堆栈中找出是自己的哪行代码引起的。其它线程同时在执行什么?有没有访问driver_M4? 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; } /* 函数代码区结束 */}====================很重要的一点是,我单步执行是可以用的,整体执行不能用。 打开call stack窗口跟进看看到底是什么断言错误 断言的截图。是ReceiveFrom报错 ReceiveFrom没用阻塞式的吧?如果当前数据缓冲区没数据用RecieveFrom会出错的,如果是阻塞式就不会有这个问题,它会阻塞在ReceiveFrom函数,直到有数据发过来. 至少要定位是哪句assert出问题吧. 应该是线程同步的问题,我把线程里面的driver_M4改成局部变量后,就没问题了。 你不是说其它线程没有用到driver_M4吗?如果是这样就与线程同步没有关系,可能是内存越界破坏了driver_M4中的数据。 是的,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); driver_M4.Connect中执行了哪些操作?也有可能是某些操作需要一段时间后才能完成,而你在线程中没有等待前面的操作完成,就继续执行了后面的操作。 发送和接受处理的太简单了。可靠的方式是发送前要检测是否可以发送;接受前要检测是否可以接收。 当然这样子处理起来要麻烦很多,但是你得考虑到网络层的感受,他有很多事要做,也可能很慢,也可能对方根本就不通,不能按照你一厢情愿的想法稀里哗啦的一路下来,发了立刻就收。简单的测试和改进, 发送和接受间插入 Sleep。具体sleep时间可以多测几组。 请教如何给list_control发送鼠标click指定行的消息 超出打开游标的最大数的问题 编辑框如何实现? 关于ClassView一点的问题?! ADO查询返回记录集的问题。 很难也,enter,回车过程 一个简单的问题,我用vc怎么复制一个文件,或者给一个文件改名 类的成员函数问题? 请问怎么在一个对话框(CDialog)里创建工具条(CToolBarCtrl)? 请教:怎样能使英文字符的宽度一样宽? 求freetype库在windows使用的详细步骤!!!! 紧急求助!关于VC图像处理
=========================
搞不定就贴代码
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;
/* 函数代码区结束 */
}
其它线程同时在执行什么?有没有访问driver_M4?
{
/* 参数定义区开始 */
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;
}
/* 函数代码区结束 */
}====================很重要的一点是,我单步执行是可以用的,整体执行不能用。
跟进看看到底是什么断言错误
断言的截图。是ReceiveFrom报错
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);