MFC重现"User Breakpoint called from code at"错误——CString在多线程中容易导致的问题

原创 2014年02月10日 14:18:42

一重现该错误

由于最近在一个项目中总是会莫名其妙的出现"User Breakpoint called from code at"错误,该错误不是每次运行的时候都出现,而是是不是会出现(Debug下),有时候10分钟,有时候则几个小时。这到底是由什么引起的呢?

由于每次运行的时候,都是与CString类相关,而且又是在多线程编程模式下,于是,就想复制该情况,重现该错误。我是这么做的。

VC6基于对话框模式新建一个工程,在CCTestMutiThreadDlg的cpp文件中所有函数外部创建一个CString类全局变量和三个操作该变量的线程函数。

CString g_str;
UINT Proc1(LPVOID param)
{
	while(1)
		g_str = "FisrtThread";
	
	return 0;
}
UINT Proc2(LPVOID param)
{
	while(1)
		g_str = "SecondThread";
	return 0;
}
UINT Proc3(LPVOID param)
{
	while(1)
		g_str = "ThirdThread";
	return 0;
}

给对话框增加一个按钮,在按钮的响应函数中添加以下代码

	AfxBeginThread(Proc1,this);
	AfxBeginThread(Proc2,this);
	AfxBeginThread(Proc3,this);
	Sleep(100000);

之后运行程序,点击对话框按钮,就可以看到弹出上述错误信息了!

二修复错误

上述错误是由于多线程访问一全局CString时,由于CString不是线程安全对象,所以导致出现错误。怎样改呢?很显然,要对线程进行同步处理。这里我们用临界区的方法进行同步。

首先在CCTestMutiThreadDlg的cpp文件中定义一个全局临界区对象CRITICAL_SECTION g_cs;

然后在按钮响应函数中线程开始之前,对临界区进行初始化和最后的删除

	InitializeCriticalSection(&g_cs);
	AfxBeginThread(Proc1,this);
	AfxBeginThread(Proc2,this);
	AfxBeginThread(Proc3,this);
	InitializeCriticalSection(&g_cs);
 	Sleep(100000);
	DeleteCriticalSection(&g_cs);
最后是同步各个线程

UINT Proc1(LPVOID param)
{
	while(1)
	{
		EnterCriticalSection(&g_cs);
		g_str = "FisrtThread";
		LeaveCriticalSection(&g_cs);
	}
	
	return 0;
}
之后运行该程序,就没有问题了。

三延展

1把全局的CString对象换成全局的int对象后,不存在上述问题

2在每个线程中加入Sleep(100);函数,暂时没有出现上述问题

3在Release版本下运行,竟然没有问题!

另,网上有这样一段话:

现象

当g_test为int,short char时,不存在多线程交叉读写错误的问题
当g_test为double, float, __int64时,存在多线程交叉读写错误的问题,对于__int64,当赋值小于0xFFFFFFFF时不出错,当大于0xFFFFFFFF时出错
当g_test为CString时,存在交叉读写错误,有时候程序崩溃
另:不加Sleep(1)机器卡死过,CPU占用率达到100%,4个核心占用率全满,可以保证运行在多核环境下

结论

1.对于int,short,char,BOOL等小于等于4字节的简单数据类型,如果无逻辑上的先后关系,多线程读写可以完全不用加锁
2.尽管float为4字节,多线程访问时也需要加锁
3.对于大于4字节的简单类型,比如double,__int64等,多线程读写必须加锁。
4.对于所有复杂类型,比如类,结构体,容器等类型必须加锁

综合来看,加锁就是了。


相关文章推荐

User breakpoint called from code at 0x7740240f 已解决

 今天在调试QQ医生时,突然蹦出来了这么个错误,使上了浑身解数,也没有定位到问题所在,只知道在 delete 一个堆上的对象时,程序就崩溃了,弹出了下面的对话框: 挺奇怪的吧,而且往往之前还弹出一个对...

vc6.0 调试中的User breakpoint called from code at 0x ....

主要有二方面的原因: 1、删除new的数组一部分 int* p = new int[10]; p = {1,1,1,1,1,1,1,1,1,1,}; delete p; 2、同一new对象删...
  • rach09
  • rach09
  • 2012年04月16日 12:44
  • 1482

user breakpoint called from code at

在调试程序中遇到提示“user  breakpoint  called  from  code  at  0x......(地址)”时,这并不一定是因没用户设置了断点的关系,而是因为系统执行了一个硬编...

不要放过User breakpoint called from code at [0x77000000]

不要放过User breakpoint called from code at [0x77000000] Mindon 2009-8-12 摘编自www.diybl.com 作者:匿名 User br...

解决“User breakpoint called from code at XXXX”Bug

转至:VC知识库hyj的Blog(除虫记之十二:费解的NTDLL断点)原贴地址:http://blog.vckbase.com/hyj/archive/2006/06/28/21006.html 除虫...
  • fpgzs2
  • fpgzs2
  • 2008年06月20日 14:59
  • 10226

对 User breakpoint called from code at XXX 问题分析汇总

分析一,转自独奏的同名Blog       今天调试程序时在Debug版跳出这个错误,我程序根本没设置断点,而其好像说是我的堆有问题,而编译了个Release版本运行正常,后来google下,查到如...

User breakpoint called from code at 0x7c92120e .

在分配内存时用到了new[ ],而在释放内存时却用的是delete,虽然程序执行没有什么大问题,只是在调试的时候总是跳出一些断点(这些个断点我没有设置),显示的内容都是:User breakpoint...

User breakpoint called from code at 0x7c92120e

分配内存时用到了new[ ],而在释放内存时却用的是delete,虽然程序执行没有什么大问题,只是在调试的时候总是跳出一些断点(这些个断点我没有设置),显示的内容都是:User breakpoint ...

STL std:string引起的User breakpoint exception/User breakpoint called from code at

STL std:string引起的User breakpoint exception/User breakpoint called from code at ...
  • lionzl
  • lionzl
  • 2011年07月05日 15:54
  • 521

[转]STL std:string引起的User breakpoint exception/User breakpoint called from code at

SYMPTOMS:  程序崩溃,弹出 User breakpoint called from code at 0x????????对话框;  崩溃时的调用栈有如下几种常见情形: (1) TDL...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:MFC重现"User Breakpoint called from code at"错误——CString在多线程中容易导致的问题
举报原因:
原因补充:

(最多只允许输入30个字)