注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

mie

 
 
 

日志

 
 

VC 2008:调试死机  

2010-08-20 19:16:14|  分类: 疑难杂症 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

最初以为是STL库的map类的问题。

 

节点:定义
 typedef struct _LAN_NODE
 {
  CString lan;
  CString path;
  CString name;
 }LAN_NODE, * P_LAN_NODE;

 map<CString, LAN_NODE>m_lan_list;

 

节点插入:
     LAN_NODE node;
     QueryStringAttribute(sub_child, CONFIG_SECTION_LAN, node.lan, CONST_STRING_NULL);
     QueryStringAttribute(sub_child, CONFIG_SECTION_LAN_NAME, node.name,

CONST_STRING_NULL);
     QueryStringAttribute(sub_child, CONFIG_SECTION_LAN_PATH, node.path,

CONST_STRING_NULL);
     node.path=m_workpath+node.path;
     m_lan_list.insert(make_pair(node.lan, node));

 

        之前,这样的代码正常,但是在修改几段代码之后(把节点插入移到一个while循环中),就出

现一个非常奇怪的现象:一旦程序运行到insert语句,机器马上假死。这时候,鼠标可以使用,但是点

击任何区域都无效!而键盘则完全失效,即使按Ctrl+Alt+Del组合键,系统也没有反应,最后只能强制

关机。

        清除解决方案,再调试,还是一样。不使用VC调试,直接运行,也是一样的结果。

 

 

跟踪结果,程序在下面的代码处出现问题

template<class _Traits> class _Tree : public _Tree_val<_Traits>


 _Pairib insert(const value_type& _Val)
  { // try to insert node with value _Val
  _Nodeptr _Trynode = _Root();
  _Nodeptr _Wherenode = _Myhead;
  bool _Addleft = true; // add to left of head if tree empty
  while (!_Isnil(_Trynode))                //————导致死机的代码
   { // look for leaf to insert before (_Addleft) or after
   _Wherenode = _Trynode;
   _Addleft = _DEBUG_LT_PRED(this->comp,
    this->_Kfn(_Val), _Key(_Trynode));
   _Trynode = _Addleft ? _Left(_Trynode) : _Right(_Trynode);
   }

  if (this->_Multi)
   return (_Pairib(_Insert(_Addleft, _Wherenode, _Val), true));
  else
   { // insert only if unique
   iterator _Where = _TREE_ITERATOR(_Wherenode);           //第二次故障处
   if (!_Addleft)
    ; // need to test if insert after is okay
   else if (_Where == begin())
    return (_Pairib(_Insert(true, _Wherenode, _Val), true));
   else
    --_Where; // need to test if insert before is okay

   if (_DEBUG_LT_PRED(this->comp,
    _Key(_Where._Mynode()), this->_Kfn(_Val)))
    return (_Pairib(_Insert(_Addleft, _Wherenode, _Val), true));
   else
    return (_Pairib(_Where, false));
   }
  }

 static _Charref _Isnil(_Nodeptr _Pnode)
  { // return reference to nil flag in node
  return ((_Charref)(*_Pnode)._Isnil);
  }


实在是没法理解,_Isnil这么简单的函数为什么会导致死机!

 

再次调试,这次步进到_Isnil里面,然后跳出,没有问题。但是执行到iterator _Where =

_TREE_ITERATOR(_Wherenode);         再次死锁!

 

看来,不是map本身的问题,而是VC调试器的问题!这样的代码可能导致VC调试器死锁!

 

改为这样的,OK!
     CString str=node.language;
     m_language_list.insert(make_pair(str, node));

 

 

然而,现在改成是在其他地方中断了!

        于是,我觉得可能是函数代码太多,导致堆栈出了问题。以前听说代码超过400行就会出问题,

我自己只遇到过一次,而且是刚学没多久的时候碰到的,所以不敢肯定。     不管怎么说,把函数改短

一些再说。

        把那个函数拆成几个函数,还是老样子!


        于是,修改程序的堆栈大小:
VC中怎样设置堆栈大小?
http://www.programfan.com/club/showpost.asp?id=89965&t=o

        结果还是一样。


        可能是静态变量导致的?静态变量占用了较多的静态数据区。这种情况以前遇到过的。

        但是这里,我使用的静态变量虽然占用较多内存,但是里面都是一些STL对象,所以,STL对象

本身使用的是静态数据区,但STL的节点数据还是使用的堆(还是new分配的)。所以,这应该不影响的。为了保

险起见,我还是试着new来分配这些全局变量。结果还是死锁!


        可能是应用程序较大?Debug之后,程序Debug版本的大小是3.25MB,代码也不过才2.5万行,所

以应该不是这个原因。以前更大的程序都没问题,现在这个不大,会有这个问题?不大可能。


        是机器的缘故?换一台机器试了试,还是一样。

 

 Release版本是否正常?
 Release版本运行时,连续依次弹出这几个提示对话框:“试图执行的操作不受支持”,“遇到

不适当的参数”。
 似乎没人遇到过这种情况。不过原因已经很清楚了,就是栈溢出!
 问题是,究竟是哪儿导致了栈溢出。这个程序还是很规范的,怎么会就出现了栈溢出?


 还是回到map上。我还是认为是map这个stl类的问题。注释掉insert语句,程序正常!insert导

致堆栈错误?或者是,VC编译insert函数的时候出了问题?(错误的代码导致错误的结果!)

 真的是快疯掉了。没想到,时至今日,自己的水平也还算可以了,还会遇到这么奇怪的问题,

而且对这个问题,我是束手无策。

 
 很可能是map的问题。以我的理解,STL库的函数都是内联函数,调用这些函数就会明显增加函

数大小。于是,我对这些insert函数的调用进行了二次封装,以便减小栈开销。然而,结果还是死锁!

根据TRACE显示的信息,事实上,我下的那些断点已经失效了!因为TRACE打印出了我的断点之外的调试

信息。
 看来,断点已经不再准确了!是其他人说的那样,缺少了symbols调试符号的缘故么?那为什么

此前没有问题?为什么去掉了insert语句就正常了呢?——不对啊!去掉insert也还是会死锁!上次是

侥幸没有死锁。


 这个问题没法下断点,因为根本没法知道它在执行哪句的时候会死机,而且一旦死机就基本上

只能重启——键盘几乎完全被屏蔽。

 list?map?改用list试试?list也还是会死锁!


 vc2008调试时出现死机
 http://group.gimoo.net/review/102792
 
 换VC版本?有点无奈。不调试的时候没事儿。
 
 vc 调试导致死机
 http://www.uipower.com/bbs/thread-84047-1-1.html
 
 NND,居然还是老问题,——只要不在那个函数里面下断点就没问题,一下断点基本上就死机,

不是什么map、list的问题。而且死机的时候,CPU疯狂地转动,那声音真有点吓人。
 
 
 没办法,既然VC 2008死机,就换VC 2005吧。使用VC 2005,改为“共享MFC链接库”链接,暂时没有再出现死锁。

 

再换回到VC 2008,改为“共享MFC链接库”链接,一切正常。
 
By: zhanyonhu

  评论这张
 
阅读(2389)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016