windows、C++、MFC、Qt项目除错笔记

原创 2013年12月03日 16:53:32

刚好今天解决了两个蛋疼的问题,就先记着,之后再补补以前的好了。

1.首先问题的现象是程序的Release版本崩溃了(Debug没有崩溃),崩溃的位置位于两个CString赋值,CString这货说实话,用了MFC这么久还真没怎么深究过,只依稀记得这货可动态改变缓冲区大小,且是通过引用计数进行内存释放的,一个赋值怎能崩溃?网上是查不到了的,因为这是不可能事件,只能自己找,我大概的解决路线如下:

(1)通过svn查看是因为加了一段代码导致,那段代码也就是简单的给wstring多赋了几个字符值,去掉则不崩溃,加上则崩溃,百思不得其解啊。

(2)崩溃的位置提示诡异,那么猜测有可能是内存损坏了,之后去检查相关调用,发现了问题的所在。

由于strlen本身是不计算\0的,在其中的一个类给char*赋值时,传入的len少给了一个\0的大小。

 

2.这个问题是关于多线程的,也是个蛋疼的问题,不过没有花费多少时间,总算是找到了。问题的现象是,MFC界面程序在经过某些操作之后,界面没有响应了(XP下发生,win7下正常)。任务管理器显示cpu为0,那么可以肯定不是死循环了,猜测到可能是多线程等待的问题。罪魁祸首是LeaveCriticalSection;由于某些同事的疏忽,在某个函数中调用了两次LeaveCriticalSection,导致后续调用EnterCriticalSection时程序等待,有点像死锁了。不过感觉还是微软实现的有问题,win7改了。

 

下面是补补之前的

3.多线程读写STL程序崩溃

同样遇到问题的人以及他们的解决方案:
http://www.tech-archive.net/Archive/VC/microsoft.public.vc.stl/2008-03/msg00027.html

我自己的解决方案是:通过发消息给窗体,等到主窗体的消息循环时,才进行处理,不直接调用接口,就可以避免多线程调用STL。

4.Windows TCP延迟问题:这个是之前做的多屏互动项目,需要通过TCP协议操作电脑,但由于TCP的延迟,导致效果不理想。找到了一个解决方案:

以下内容是从别处转载的:

TCP本身属面向链接的通讯协议。通讯双方的每一个收发动作,需要以通讯链路正常为前提。因此TCP协议内部提供了默认的ACK验证机制。而ACK验证方式存又与操作系统有关,在TCP中,对数据的确认往往是延迟的,在时延定时器没有溢出的情况下,一般情况是两个TCP数据对应一个确认,如果时延定时器溢出了,那么自然也会发送确认报文。但在某些系统中,会出现必须每次回复ACK包才继续发送TCP数据,这时就会出现以下问题:假定Server A、和Client B之间建立了一个TCP连接,某一时刻A第一次向B发送数据,发送完成后等待B回复的ACK包,而B认为收到第二个TCP数据包才回复ACK标记,则约200ms之后,B中的时延定时器溢出,B此时才向A回发一个长度为1的ACK确认包,因此B第二次收到数据时,会莫名其妙的产生一个约200ms的延时——这个延时不是别的,正是ACK确认包默认的发送时延。
      当我们测试自行研发的服务端通讯框架时,一旦其发生广播,则此时处于接收方的客户端很有可能会因为通讯双方的收发不均而引发上述现象——这并非是由于你的服务端通讯框架性能不达标,而是由于TCP的内部机制导致的。
那么,我们应该如何避免这种情况呢?这里介绍一种最简单也最容易实现的方法——修改注册表,提高客户端ACK包默认的发送频率,也就是缩短ACK包的发送时延:
首先,点击你电脑屏幕左下角的“开始”菜单,打开“运行”,键入“regedit”打开你的注册表;
选择HKEY_LOCAL_MACHINE 项目开始一层层的往下点,一直到
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/services/Tcpip/Parameters/Interfaces
这里是关于你网卡的数据,有很多项,且它们都有类似{5F26EBBD-9CA6-4219-9DBD-54852364EA17}这样的名字,但是正确的那个会在右边窗口显示包括你的IP地址和你的服务器IP地址等等网络设定)。 你找到IPAddress项符合你的本机IP地址的那个,那么它就是你连接网络的那个网卡的设定项,我们的任务目标就是改动它来提高客户端ACK包的发送频率。
其次,右键点击窗口右边的空白处,“新建”-“DWORD值”;
给它改名成“TcpAckFrequency”,然后右键点击它 ,选择"修改”,然后再那个"数值数据"的空白处填"1"(不用管是16进制,还是10进制)
最后,关闭注册表,重启电脑,修改完成。

有关TcpAckFrequency的补充说明:
TcpAckFrequency 值这个值确定了windows用TCP/IP 发送应答消息的频率,也就是决定了在发送“命令正确应答”之前将等候几个数据包;
默认值为 2,这时TCP/IP 将在接收到 2 个分段后发送应答,或是在接收了 1 个分段但在 200 毫秒内没有接收到其他分段的情况下发送应答
如果值为 3,则 TCP/IP 将在接收到 3 个分段后发送应答,或是在接收了 1 个或 2 个分段但在 200 毫秒内没有接收到其他分段的情况下发送应答,以此类推。
如果需要通过消除 TCP/IP 应答延迟来缩短响应时间,则将该值设为 1。在这种情况下,Windows将每收到一个TCP数据包就回送一个“命令正确应答”。
该值的有效范围是 0 到 255,其中 0 表示使用缺省值(2)。

采用Delayed ACK机制后,通常是服务端发送2个数据包后,客户端再进行确认,这样将极大的减少不必要的ACK数据包,同时也能提高访问速度,减少带宽浪费。
修改方法:
在注册表中添加键值进行修改;
HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesTcpipParametersInterfacesAdapter GUID
值名称:TcpDelAckTicks(不同的操作系统该值的名称不尽相同)
数据类型:REG_DWORD
值数据:将该值设置为 0 到 6 之间的值
默认情况下,延迟 ACK 计时器值为 200 毫秒。如果将 TcpDelAckTicks 值设置为 0,则禁用延迟确认。

5.windows 7 高DPI UI错乱的解决办法

微软自己有提供解决方案,我们采用就可以了:

csdn上有个帖子:
http://bbs.csdn.net/topics/370177760

微软官方的解决方案:
http://msdn.microsoft.com/en-us/library/windows/desktop/dd464660(v=vs.85).aspx

微软给出了一个CDPI类封装了转换函数,之后可以用这个进行常规替换,解决起来应该是很方便的。



6.Win7多点触摸VS2010以及后续版本单点长按右键问题解决方案

做触摸应用这点很重要啊

http://connect.microsoft.com/VisualStudio/feedback/details/699523/tablet-pc-right-click-action-cannot-invoke-mfc-popup-menu

 

7.不能通过CCmdUI *pCmdUI改变对话框菜单状态的问题

 

需求描述:需要在对话框右键菜单做出类似word大纲级别的右键菜单

在普通的菜单中这个是很简单很简单的,但是由于在对话框中,动态创建菜单,并且在菜单前加上【•】 这样的选中符号。辛苦之后找到解决方案
Cause:
When a drop-down menu is displayed, the WM_INITMENUPOPUP message is sent prior to displaying the menu items. The MFCCFrameWnd::OnInitMenuPopup function iterates through the menu items and calls the update command UI handler for the item, if there is one. The appearance of each menu item is updated to reflect its state (enabled/disabled, checked/unchecked).

The update UI mechanism doesn't work for a dialog box-based application because CDialog has no OnInitMenuPopup handler and it uses CWnd's default handler, which does not call update command UI handlers for menu items.

Rusolution:
http://student.csdn.net/space.php?uid=44375&do=blog&id=38685

8.win 7窗体置顶问题(MFC)

相信很多人都遇到了,在网上搜索了很多方法,什么先AttachThreadInput到顶层窗体然后SetForegroundWindow,以及什么SystemParametersInfo关闭SPI_SETFOREGROUNDLOCKTIMEOUT属性,然后SetForegroundWindow在开启,能试的方法都试过了,都不能理想的让窗体置顶(MFC多文档窗体,有不同模式,需要在全屏模式下置顶),最后还是自己试验除了一套组合,

SetWindowPos(&wndTopMost,0,0,0,0,SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE);
::SetForegroundWindow(this->GetSafeHwnd());
SetWindowPos(0,0,0,0,0,SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE);

前两个方法必须一起调用才有效果,最后那个是为了只置顶一次才添加。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

windows用户态程序高效除错.pdf

  • 2013年01月17日 05:42
  • 1.93MB
  • 下载

windows 2003 除錯與災難回復

  • 2014年09月25日 08:43
  • 652KB
  • 下载

debugger:除错,安全监控,优化,修改

调试即是对指令流顺序进行跟踪和干预,对码流内容进行识别的工具,用来分析程序的行为过程和目的。调试工具依赖具体系统,x86或者java虚拟机,或者其他执行系统。 1、windows sdk中包含win...
  • uhml
  • uhml
  • 2014年04月04日 16:55
  • 597

程序匠人 - 程序调试(除错)过程中的一些雕虫小技

转自:http://bbs.21ic.com/icview-128517-1-1.html 一、前言 调试程序,是软件开发过程中的一个必不可少的环节。这篇帖子,匠人试着来整理一下一些调试的技巧。 ...

message sent to deallocated instance 除錯

原文地址:http://kenobiluh.blogspot.com/2011/04/message-sent-to-deallocated-instance.html 常常程式一長,哪邊就...
  • mqlsq
  • mqlsq
  • 2012年05月16日 17:34
  • 743

message sent to deallocated instance 除錯

常常程式一長,哪邊就不小心多release了一次 這時候編譯器就只會告訴你:BAD_ACCESS,然後程式就死了 剛開始會google到去Argument加個NSZombieEnabled YES...

Javah 常见错误记录-NDK与JNI除错

测试文件:hello-jni/src/com/example/hellojni/HelloJni.java   [Java] view plaincopyprint? /**...

代码大全学习-26-调试除错(Debugging)

调试,号称是软件开发过程中最耗时的工作,无数的开发人员在上面花费了无数的时间。毫无疑问,想办法提高调试的效率是非常有用的。那么关键在哪里呢?就是要用科学的方法。     相信所有的开发人员都有这样的...
  • tyst08
  • tyst08
  • 2012年09月09日 17:37
  • 699

Windows Forms、 MFC、WTL、 WxWidgets、Qt、GTK

图形界面库Windows Forms、 MFC、WTL、 WxWidgets、Qt、GTK 综合比较见下表: 总结: GTK+主要用在X Window上,整个设计的架构和许多概念和MFC以及一般 W...

【SrpingBoot】SpringBoot内置Tomcat报错+除错小技巧

今天运行程序的时候,发现如下错误: 根据网上博客的观点,是因为Tomcat端口被占用,当时用最low的办法,ctrl+alt+delete调出后台,把java.exe全关了,然后重启程序就好了,简...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:windows、C++、MFC、Qt项目除错笔记
举报原因:
原因补充:

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