WinDbg 解决Font.ToLogFont AccessViolationExcetion
有个程序总是在windows 2003 server 异常退出. 并且, 查看调用栈也肯奇怪, 应该是很正常的调用. 怀疑是堆溢出.
开启heap trace :
C:\Program Files\Debugging Tools for Windows (x86)>gflags -i app.exe +ust +hpa
发现在Font.ToLogFont函数遇到: {"Attempted to read or write protected memory. This is often an indication that other memory is corrupt."}
如下图:

用Windbg打开exe后发现:
(12e8.13e4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=07362e9c ebx=00000001 ecx=00000003 edx=4dd77680 esi=07362f4c edi=09b03000
eip=4ddccc1c esp=0012e894 ebp=0012e8e8 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010206
gdiplus!GpFont::GetLogFontW+0x12d:
4ddccc1c f3a5 rep movs dword ptr es:[edi],dword ptr [esi]
汇编代码:
4ddccc11 8b7004 mov esi,dword ptr [eax+4]
4ddccc14 6a10 push 10h
4ddccc16 03f0 add esi,eax
4ddccc18 83c71c add edi,1Ch
4ddccc1b 59 pop ecx
4ddccc1c f3a5 rep movs dword ptr es:[edi],dword ptr [esi]
重新运行程序,在4ddccc1b处打断点,
0:007> bp 4ddccc1b
0:007> g
Breakpoint 0 hit
eax=07362e9c ebx=00000001 ecx=5d5be675 edx=4dd77680 esi=07362f18 edi=080b2fdc
eip=4ddccc1b esp=0012e890 ebp=0012e8e8 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
gdiplus!GpFont::GetLogFontW+0x12c:
4ddccc1b 59 pop ecx
查看edi所在堆还有多少可写空间,
0:000> !heap -p -a edi
address 080b2fdc found in
_DPH_HEAP_ROOT @ 151000
in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize)
9bf6380: 80b2fc0 3c - 80b2000 2000
7c83d7f0 ntdll!RtlAllocateHeap+0x00000e9f
776bcfde ole32!CRetailMalloc_Alloc+0x00000016
776bcf4b ole32!CoTaskMemAlloc+0x00000013
79ac4920 mscorlib_ni+0x00244920
79aca07b mscorlib_ni+0x0024a07b
79ab516a mscorlib_ni+0x0023516a
7b1effc4 System_Drawing_ni+0x0004ffc4
7b1e46c0 System_Drawing_ni+0x000446c0
7b1e452d System_Drawing_ni+0x0004452d 0:000> ? 80b2fc0+ 0x3c - edi
Evaluate expression: 32 = 00000020
剩余32字节.
而ecx指示需要写入0x10 * 4=0x40字节:
0:000> p
eax=07362e9c ebx=00000001 ecx=00000010 edx=4dd77680 esi=07362f18 edi=080b2fdc
eip=4ddccc1c esp=0012e894 ebp=0012e8e8 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
gdiplus!GpFont::GetLogFontW+0x12d:
4ddccc1c f3a5 rep movs dword ptr es:[edi],dword ptr [esi]
显然不够用, 执行后抛出AV:
(6d8.1310): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=07362e9c ebx=00000001 ecx=00000007 edx=4dd77680 esi=07362f3c edi=080b3000
eip=4ddccc1c esp=0012e894 ebp=0012e8e8 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202
gdiplus!GpFont::GetLogFontW+0x12d:
4ddccc1c f3a5 rep movs dword ptr es:[edi],dword ptr [esi]
0:000> ?(3c - 20)/4
Evaluate expression: 7 =
ecx 还剩7个DWORD写不下.
原因是什么??
LOGFONT在C#中定义是:
[StructLayout(LayoutKind.Sequential)]
private class LOGFONT
{
public int lfHeight = ;
public int lfWidth = ;
public int lfEscapement = ;
public int lfOrientation = ;
public int lfWeight = ;
public byte lfItalic = ;
public byte lfUnderline = ;
public byte lfStrikeOut = ;
public byte lfCharSet = ;
public byte lfOutPrecision = ;
public byte lfClipPrecision = ;
public byte lfQuality = ;
public byte lfPitchAndFamily = ;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32) ]
public string lfFaceName = "";
}
WinGDI.h定义:
/* Logical Font */
#define LF_FACESIZE 32 typedef struct tagLOGFONTA
{
LONG lfHeight;
LONG lfWidth;
LONG lfEscapement;
LONG lfOrientation;
LONG lfWeight;
BYTE lfItalic;
BYTE lfUnderline;
BYTE lfStrikeOut;
BYTE lfCharSet;
BYTE lfOutPrecision;
BYTE lfClipPrecision;
BYTE lfQuality;
BYTE lfPitchAndFamily;
CHAR lfFaceName[LF_FACESIZE];
} LOGFONTA, *PLOGFONTA, NEAR *NPLOGFONTA, FAR *LPLOGFONTA;
看上去没有任何问题啊!!
但是 gdiplus并没有按照CHAR来处理传入进去的字符串, 相反, 是按照WCHAR来处理的.
WinGDI.h对于宽字符的LOGFONT定义是:
typedef struct tagLOGFONTW
{
LONG lfHeight;
LONG lfWidth;
LONG lfEscapement;
LONG lfOrientation;
LONG lfWeight;
BYTE lfItalic;
BYTE lfUnderline;
BYTE lfStrikeOut;
BYTE lfCharSet;
BYTE lfOutPrecision;
BYTE lfClipPrecision;
BYTE lfQuality;
BYTE lfPitchAndFamily;
WCHAR lfFaceName[LF_FACESIZE];
} LOGFONTW, *PLOGFONTW, NEAR *NPLOGFONTW, FAR *LPLOGFONTW;
因此是C#中的定义lfFaceName长度只有一半!
解决方法就是C#中定义 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
WinDbg 解决Font.ToLogFont AccessViolationExcetion的更多相关文章
- WinDbg解决BHO不加载
昨天zhengwei同学说他机器上的一个BHO不能正常加载,我把BHO的代码拿过来,在我的两台机器上都验证了一下,一台是Win7+IE8的环境,一台是XP+IE7的环境,都能正常加载.zhengwei ...
- Windbg解决系统蓝屏
win10企业版连续两天遭遇系统蓝屏, 今天就各种检查,准备好好地研究一下这个问题,以下是整个过程: 首先,找到系统蓝屏时的错误日志: [计算机] --> [管理] --> [系统工具] ...
- WINDBG解决cpu占高的问题
https://blog.csdn.net/yenange/article/details/62886988 https://blog.csdn.net/zhushentian/article/det ...
- 再记一次w3wp占用CPU过高的解决过程(Dictionary和线程安全)
在此之前项目有发生过两次类似的状况,都得以解决,但最近又会发现偶尔CPU会跑满,虽然之前使用过WinDbg解决过两次问题但人的记忆是不可靠的,今天处理同样问题的时候还是遇到了一些障碍,这一次希望可以记 ...
- 记一次w3wp占用CPU过高的解决过程(Dictionary和线程安全)
项目上线以来一直存在一个比较揪心的问题,和一个没有信心处理的BUG,那就是在应用程序启动时有可能会导致cpu跑满99%或持续在一个值如50%左右,这样一来对服务器的压力是非常大的,经常出现服务器无法远 ...
- 改变 font Awesome、Ionic 图标属性
可使用 -webkit-text-stroke属性. 例如: -webkit-text-stroke:1px red 使用color属性,可改变 图标颜色: 例如: color: red: 使用fon ...
- Windbg(2)
摘抄于:http://www.cnblogs.com/awpatp/category/228209.html Debug相关的一些小技巧 摘要: 1. 如何Debug一个进程的子进程? 答: 使用Wi ...
- windbg(1)
1.http://www.cnblogs.com/huangyong9527/category/384128.html 2.http://www.cnblogs.com/pugang/category ...
- Goodbye2014,Hello2015
正如我在研发会议上说的,总结是为了更好的计划:而计划,则是让你做事有目标,有方向:有了目标和方向,你才能真正把事情做成! 总的来说2014年可以归纳为下图: 2014年总结 一年的活动,基本可以归纳为 ...
随机推荐
- leetCode(29):Happy Number
Write an algorithm to determine if a number is "happy". A happy number is a number defined ...
- ubuntu执行级别,设置单用户模式
redhat的runlevel级别定义例如以下: 0:关机.不能将系统缺省执行级别设置为0,否则无法启动. 1:单用户模式.仅仅同意root用户对系统进行维护. 2:多用户模式.但不能使用NFS( ...
- APACHE + LDAP 的权限认证配置方法
原文地址:http://www.chinaunix.net/jh/49/627646.html 一.前言 很多朋友希望利用 Apache 通过 LDAP 进行用户认证及权限管理. 通过多次试验 ...
- Ubuntu 分区方案参考
2011-10-25 10:09 对于初次接触的一般用户(包括双系统用户): / 5-10G(玩玩的话5G就够,长期使用的话推荐10G) /usr 5-10 ...
- Android虚拟键盘弹出时挡住EditText解决方法
在manifest的activity节点使用 Xml代码 <activity android:windowSoftInputMode="adjustResize"/> ...
- C#: 数字经纬度和度分秒经纬度间的转换
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...
- django Proxy models ---- 代理模式
一个proxy models 不会在数据库中创建新的表.而是与它的基类共用同一个表 1.model 的定义: from django.db import models # Create your mo ...
- Atitit.注册跟个登录功能的实现attilax总结obo
Atitit.注册跟个登录功能的实现attilax总结obo 1. 注册模块 2 1.1. 基本注册功能(用户名方式) 2 1.2. 动态ajax监测用户名重复 2 1.3. 注册手机验证 2 1.4 ...
- delphi无边框可拖动窗体
unit UFrmModless; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, ...
- Linux 进程资源用量监控和按用户设置进程限制
每个 Linux 系统管理员都应该知道如何验证硬件.资源和主要进程的完整性和可用性.另外,基于每个用户设置资源限制也是其中一项必备技能. 在这篇文章中,我们会介绍一些能够确保系统硬件和软件正常工作的方 ...