windbgjava的简单介绍
今天给各位分享windbgjava的知识,其中也会对进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:
- 1、如何用WinDbg定位内存泄露
- 2、黑客是不是几乎会所有编程语言,编程小白,纯属好奇
- 3、考C语言二级的时候编写程序设计题为什么调试是灰色的?
- 4、关于Windows内核编程的问题
- 5、如何在.net应用中发现和避免内存和资源泄露
如何用WinDbg定位内存泄露
一般我用两种方法:
1. 用Debug Diagnostic Tool的Leak监测分析功能,注意配置好PDB文件。
DebugDiag 会生成完整的Leak Report。看看帮助很方便。
2. 用WinDBG的!heap扩展命令。注意要为你的程序打开Normal PageHeap。
然后当内存出现明显泄漏时用 !heap -l 命令分析内存。-l 参数使用类似Java/C#的Garbage Collection算法,这样能找到大部分在程序中没有被引用的HeapBlock。
这是一个示例输出:
0:011 !heap -l
Searching the memory for potential unreachable busy blocks.
......
Heap 017a0000
Scanning VM ...
Scanning references from 3586 busy blocks (0 MBytes) ...
Entry User Heap Segment Size PrevSize Unused Flags
-----------------------------------------------------------------------------
00253198 002531a0 00250000 00250000 b8 78 14 busy extra
00253250 00253258 00250000 00250000 78 b8 13 busy extra
00286a38 00286a40 00250000 00250000 b8 b8 15 busy extra
00286af0 00286af8 00250000 00250000 b8 b8 15 busy extra
00286ba8 00286bb0 00250000 00250000 b8 b8 15 busy extra
00286c60 00286c68 00250000 00250000 b8 b8 15 busy extra
00286d18 00286d20 00250000 00250000 b8 b8 15 busy extra
00286dd0 00286dd8 00250000 00250000 b8 b8 15 busy extra
找到最常出现的Size值(这里是b8),一般就是持续泄漏的内存块大小。随便选一行,记下Entry地址(比如00286a3)。
dt _DPH_BLOCK_INFORMATION 00286a3 + 8 //8 是HeapEntry结构的大小,跟在其后的就是PageHeap meta data,结构名是_DPH_BLOCK_INFORMATION.
0:011 dt _DPH_BLOCK_INFORMATION 00286a3+ 8
ntdll!_DPH_BLOCK_INFORMATION
+0x000 StartStamp : 0xabcdaaaa
+0x004 Heap : 0x80151000
+0x008 RequestedSize : 0x7b
+0x00c ActualSize : 0xa3
+0x010 FreeQueue : _LIST_ENTRY [ 0x2e - 0x0 ]
+0x010 TraceIndex : 0x2e
+0x018 StackTrace : 0x00357140
+0x01c EndStamp : 0xdcbaaaaa
看到StackTrace那行,这是相应的user mode stack trace database的地址。
0:011 dds 0x00357140
00357140 abcdaaaa
......
00357160 7c949d18 ntdll!RtlAllocateHeapSlowly+0x44
00357164 7c91b298 ntdll!RtlAllocateHeap+0xe64
00357168 004017fe 06_DebugDiag_MemoryLeak!MyHeapAlloc+0x1e [g:\debugging101\projects\06_debugdiag_memoryleak\06_debugdiag_memoryleak\06_debugdiag_memoryleak.cpp @ 11]
0035716c 0040182b 06_DebugDiag_MemoryLeak!WorkerThread+0x1b [g:\debugging101\projects\06_debugdiag_memoryleak\06_debugdiag_memoryleak\06_debugdiag_memoryleak.cpp @ 27]
00357170 7c80b683 kernel32!BaseThreadStart+0x37
这就是上次通过Heap Manager函数操作这个HeapBlock的StackTrace,一般也就是分配这个Block的地方。
希望可以帮到你。
黑客是不是几乎会所有编程语言,编程小白,纯属好奇
其实不是这样的,只要精通一门语言,也是可以成为黑客的,一般语言的话,可以学习C/C++,python,但是如果真要当真正的黑客,要学的东西就很多了: 英文能看懂外国论坛, 计算机原理, 计算机语言: 汇编必须的, 其它精通几门。还有各种逆向工具: OD, CE, IDA, PEID,WinDbg等等.
考C语言二级的时候编写程序设计题为什么调试是灰色的?
没关系,程序设计是结果正确就得分。
C语言程序的调试,主要取决于调试器的使用,比如windows可以使用VC/vs内置的调试器,也可以使用WinDbg(微软自己的专业调试器),也可以使用OllyDbg(环3级最常用的动态调试器),不同的调试器具体用法肯定不一样,但原理和核心操作类一样。
C语言是一门面向过程的、抽象化的通用程序设计语言,广泛应用于底层开发。C语言能以简易的方式编译、处理低级存储器。
C语言是仅产生少量的机器语言以及不需要任何运行环境支持便能运行的高效率程序设计语言。尽管C语言提供了许多低级处理的功能,但仍然保持着跨平台的特性,以一个标准规格写出的C语言程序可在包括类似嵌入式处理器以及超级计算机等作业平台的许多计算机平台上进行编译。
C语言的应用:
C语言是一门面向过程的计算机编程语言,与C++、C#、Java等面向对象编程语言有所不同。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、仅产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。
C语言描述问题比汇编语言迅速、工作量小、可读性好、易于调试、修改和移植,而代码质量与汇编语言相当。C语言一般只比汇编语言代码生成的目标程序效率低10%-20%。因此,C语言可以编写系统软件。
关于Windows内核编程的问题
其实Windows内核编程不但有用,而且常用。很多我们每天都使用的软件,就毫无疑问的使用了Windows内核编程的技术。最典型的就是实时监控的杀毒软件。此外还有防火墙、虚拟光驱、以及90%的驱动程序。这些程序的有一个共同的特点,他们的一部分组件,是作为Windows的一部分,能对 Windows上运行的所有的应用程序起作用。
因此内核编程的应用,往往给传统软件带来更强的功能,实现技术上的飞跃。
举个例子。我们常常听说,对文件进行加密,可以使文档更加安全。对文件加密并不需要任何内核组件。我们可以写一个应用程序,读入文件,加密数据,然后重写为一个加密文件。解密也可以同样如此。
但是实际上这并不满足一般的用户需求。对一个公司的员工来说,那些“重要的文档”很可能就是每天工作所用的文件。想象一下,他必须要每天从服务器上下载加密的文件,然后用解密工具解密。然后用Office开始工作。工作完毕后,用加密工具加密,再上传,然后删除工作文档。且不说大部分时间文档是以解密的方式保存在硬盘上的不安全性,这个工作流程是可以接受的吗?没有人会接受的。
比较“人性化”的方式就是让Office可以直接打开已经加密的文档。保存的时候,直接就保存成加密的文档。硬盘上,这个文档始终是加密的。而且对合法的用户透明。对非法的用户,则只能看见密文,从而无法编辑也无法阅读。而且也不仅仅Office,还有AutoCAD、Visual Studio、Photoshop等等用户可能用于编辑机密文件的所有的工具。这是可以实现的吗?如果我们不能去修改Office和其他的工作软件。
这当然是可以实现的。既然我们编写Windows内核程序,当然可以让Windows的文件系统从硬盘读取文件的时候,对特定的进程进行特别的解密。等这些软件读取到数据的时候,它们读到的已经是正常的数据了。这个过程和实时扫描病毒的原理是一样的,使用一个文件过滤驱动程序。这就是读者可能已经听到过的文件透明加密技术。
在和《天书夜读:从汇编语言到Windows内核编程》一书同一系列的《寒江独钓——Windows内核编程与信息安全》(预计明年出版)中,对键盘过滤、硬盘过滤、文件过滤、网络过滤等安全相关的内核编程,都有详尽的讲解和例子。
内核编程的另一个特点是:这些代码运行在R0级。R0级别是最高特权级别。对CPU有完全控制的能力。这非常的适合一些安全软件,当然也适合做破坏的工作。因为内核程序有最高(也就是根)权限,这样的技术在安全领域(或者破坏领域)被称为rootkit技术。rootkit技术是当前安全领域最热门的技术之一。
许多病毒使用了rootkit技术。用来隐藏病毒文件,窃取密码、发送攻击包等等。rootkit病毒感染后极难清除,在感染前提前防范是最有效的办法。
Windows内核确实没有公开源代码。但是MS提供Windows内核程序的开发包:WDK。WDK实际上主要用于开发驱动程序。而驱动程序基本上都是内核程序。WDK提供的头文件以及部分源代码,实际上就是Windows内核的代码的一部分。有部分驱动程序(比如FAT32文件系统)的代码是完全公开的。我们也可以在这里看到Windows内核开发者的代码风格。同时,微软也提供了所有Windows版本的符号表在网上供研究者下载。并提供了功能无比强大的调试器WinDbg。有了它们,你就可以轻松的调试Windows内核了。无论是你自己写的代码的部分,还是Windows内核开发者们编写的部分。虽然看到的是汇编语言,但是函数名和全局变量名都是存在的。而且,所有的这些(WDK、WinDBG,符号表)都是免费的。
如何在.net应用中发现和避免内存和资源泄露
尽管很多人相信在.net应用中谈及内存及资源泄露是件很轻松的事情。但GC(垃圾回收器)并不是魔法师,并不能把你完全从小心翼翼处理内存与资源损耗中解放出来。
本文中我将解释缘何内存泄露依然存在以及如何避免其出现。别担心,本文不涉及GC内部工作机制及其它.net的资源及内存管理等高级特性中。
理解泄露本身及如何避免其出现很重要,尤其因为它无法轻松地自动检测到。单元测试在此方面无能为力。一旦产品中你的程序崩溃了,你需要马上找出解决方案。所以在一切都还不是太晚前,花些时间来学习一下本文吧。
Table of Content
· 介绍
· 泄露?资源?指什么?
· 如何检测泄露并找到泄露的资源
· 常见内存泄露原因
· 常见内存泄露原因演示
· 如何避免泄露
· 相关工具
· 结论
· 资源
介绍
近期,我参与了一个大的.net项目(暂叫它项目X吧),我在项目中负责追踪内存与资源泄露。大部分时间我都花在与GUI关联的泄露上,更准确地说是一个基于Composite UI Application Block (CAB).的windows窗体应用。接下来我要说的直接应用到winform上的内容,多数见解同样可以适用到其它.net应用中(像WPF,Silverlight,ASP.NET,Windows service,console application 等等)。
我不是个处理泄露方面的专家,所以我不得不深入钻研了一下应用程序,做一些清理工作。本文的目标是与你们分享在我解决问题过程中的所得所悟。希望能够帮助那些需要检测与解决内存、资源泄露问题的朋友。下面的概述部分首先会介绍什么是泄露,之后会看看如何检测到泄露和被泄露资源,以及如何解决与避免类似泄露,最后我会列出一个对此过程有帮助的工具列表及相关资源。
泄露?资源?指什么?
内存泄露
在进一步深入前,让我们先来定义下我所谓的“内存泄露”。简单引用在Wikipedia上找到的定义吧。该定义与我打算通过本文所帮助解决的问题完美的一致:
在计算机科学领域中,内存泄露是指一种特定的内存损耗,该损耗是由一个计算机程序未成功释放不需要的内存引起的。通常是程序中的BUG阻碍了不需要内存的释放。
仍然来自Wikipedia:”以下语言提供了自动的内存管理,但并不能避免内存泄露。像 Java,C#,VB.NET或是LISP等。”
GC只回收那些不再使用的内存。而使用中的内存无法释放。在.net中,只要有一个引用指向的对象均不会被GC所释放。
句柄与资源
内存可不是唯一被视为资源的。当你的.net应用程序在Windows上运行时,消耗着一个完整的系统资源集。微软定义了系统三类对象:用户(user),图形设备接口(GUI),以及系统内核(kernel)。我不会在此给出完整的分类对象列表,只是指出一些重要的:
· 系统通过使用用户对象(User objects) 来支持windows管理。相关对象包括:提速缓冲表(Accelerator tables),Carets(补字号?),指针(Cursors),钩子(Hooks),图标(Icons),菜单(Menus)和窗体(Windows)。
· GDI对象 支持图形绘制:位图(bitmaps),笔刷(Brushes),设备上下文(DC),字体(Fonts),内存设置上下文(Memory DCs),元文件(Metafiles),画笔(Pens),区域(Regions)等。
· 内核对象 支持内存管理,进程执行和进程间通讯(IPC):文件,进程,线程,信号(Semaphores),定时器(Timer),访问记号(Access tokens),套接字(Sockets)等。
所有系统对象的详细情况都可以在MSDN中找到。
系统对象之外,你还会碰到句柄(handles).据MSDN的陈述,应用程序不能直接访问对象数据或是对象所代表的系统资源。取而代之,应用程序一定都会获得一个对象句柄(Handle),可以使用它检查或是修改系统资源。在.net中无论如何,多数情况下系统资源的使用都是透明的,因为系统对象与句柄都由.net类直接或间接代表了。
非托管资源
像系统对象(System objects)这样的资源自身都不是个问题,但本文仍涵盖了它们,因为像Windows这样的操作系统对可同时打开的 套接字、文件等的数量都有限制。所以关注应用程序所使用系统对象的数量非常重要。
在特定时间段内一个进程所能使用的User与GDI对象数目也是有配额的。缺省值是10000个GDI对象和10000个User对象。如果想知道本机的相关设置值,可以使用如下的注册表键:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows: GDIProcessHandleQuota 和 USERProcessHandleQuota.
猜到了什么?确实没有这么简单,还有一些你会很快达到的其它限制。比如参照:我的一篇有关桌面堆的博客 所述。
假设这些值是可以自定义的,你也许认为一个解决方案就是打破默认值的限制—调高这些配额。但我认为这可不是个好主意,有如下原因:
1. 配额存在的原因:系统中不是只有你独自一个应用程序,所有运行在计算机中的其它进程与你的应用应该分享系统资源。
2. 如果你修改配额,使它不同于其它系统了。你不得不确认所有你的应用程序需要运行的机器都完成了这样的修改,而且这样的修改从系统管理员的角度来说是否会有问题也需要确认。
3. 大部分都采用了默认配额值。如果你发现配置值对你应用程序来说不够,那你可能确实有些清理工作要做了。
如何检测泄露及找到泄露的资源
泄露带来的实际问题在MSDN上的一篇文章中有着很好的描述:
哪怕在小的泄露只要它反复出现也会拖垮系统。
这与水的泄露异曲同工。一滴水的落下不是什么大问题。但是一滴一滴如此反复的泄露也会变为一个大问题。
像我稍后解释的,一个无意义的对象可以在内存中维持一整图的重量级对象。
仍然是同一篇文章,你会了解到:
通常三步根除泄露:
1.发现泄露
2.找到被泄露的资源
3.决定在源码中何时何处释放该资源
最直接“发现”泄露的方式是遭受泄露引发的问题
你或许没有见过内存不足。“内存不足”提示信息极少出现。因为操作系统运行中实际内存(RAM)不足时,它会使用硬盘空间来扩展内存。(称为虚拟内存)。
在你的图形应用程序中可能更多出现的是“句柄不足”的异常。准确的异常不是System.ComponentModel.Win32Exception 就是 System.OutOfMemoryException 均包含如下信息:”创建窗体句柄错误”。这两个异常多发于两个资源被同时使用的情况下,通常都因为该释放的对象没有被释放所致。
另外一种你会经常碰到的情况是你的应用程序或是整个系统变更得越来越慢。这种情况的发生是因为你的系统资源即将耗尽。
我来做个生硬的推断:大多数应用程序的泄露在多数时间里都不是个问题,因为由泄露导致出现的问题只在你的应用程序集中使用很长时间的情况下才会出现。
如果你怀疑有些对象在应该被释放后仍逗留在内存中,那需要做的第一件事就是找出这些对象都是什么。
这看起来很明显,但是找起来却不是这样。
建议通过内存工具找到非预期逗留在内存中的高级别对象或是根容器。在项目x中,这些对象可能是类似LayoutView实例一样的对象们(我们使用了MVP(Model View Presentation )模式)。在你的实际项目中,它可能依赖于你的根对象是什么。
下一步就是找出它们该消失却还在的原因。这才是调试器与工具能真正帮忙的。它们可以显示出这些对象是如何链接在一起的。通过查看那些指向“僵尸对象”(the zombie object)的引用你就可以找到引起问题的根本原因了。
你可以选择 ninja方式(译者:间谍方式?)(参照 工具介绍章节中有关 SOS.dll 和 WinDbg 的部分)。
我在项目X中用了JetBrains的dotTrace,本文中我将继续使用它来介绍。在后面的工具相关章节中我会向你更多的介绍该工具。
你的目标是找到最终引起问题的那个引用。不要停留在你找到的第一个目标上,但是也要问问自己为什么这个家伙还在内存中。
常见内存泄露的原因
上面提到的泄露情况在.net中较常见。好消息是造成这些泄露的原因并不多。这意味着当你尝试解决一个泄露问题时,不需要在大量可能的原因间搜寻。
我们来回顾一下这些常见的罪魁祸首,我把它们区别开来:
· 静态引用
· 未注销的事件绑定
· 未注销的静态事件绑定
· 未调用Dispose方法
· Dispose方法未正常完成
除了上列典型的原因外,还有些其它情况也可能引发泄露:
· Windows Forms:绑定源滥用
· CAB:未移除对工作项的调用
我只列出了可能在你应用程序中出现的一些原因,但应该清楚你的应用程序依赖的其它.net代码、库实际使用中也可能引发泄露。
我们来举个例子。在项目x中,使用了一套第三方控件来构造界面。其中一个用来显示所有工具栏的控件,它管理着一个工具栏列表。这种方式没什么,但有一点,即使被管理的工具栏自身实现了IDisposable接口,管理类却永远也不会去调用它的Dispose方法。这是一个bug.幸运的是这发生在一个很容易发现的工作区:只能我们自身来调用所有工具样的Dispose方法了。不幸的是这还不够,工具栏类自身问题也不少:它并没有释放自身承载的控件(按钮,标签等等)。所以在解决方案中还要添加对每个工具栏中控件的释放,但是这次可就没那么简单了,因为工具栏中的每个子控件都不同。不管怎么样这只是一个特殊的例子,我要表达的观点是你应用程序中使用的任何第三方库、组件都可能引发泄漏。
最后,还有一种由.net framework造成的泄露,由一些不好的使用习惯引起。即使.net framework自身可能引发泄露,但这是你极少会遭遇到的情况。把责任推到.net身上很容易,但在我们把问题推到别人头上前,还是应该先从自身写的代码出发,看看里面有没有问题。
常见泄露演示
我已经列举出了泄露主要的来源,但我还不想仅限于此。如果每个泄露我都能举个鲜活的例子的话,我想本文会更实用些。好,我们先启动Vs 和 dotTrace , 然后看些示例代码。我会同时演示如何解决或是避免每个泄露情况。
项目X中使用了CAB和MVP模式,这意味着界面由工作空间、视图和呈现者组成。简单起见,我决定使用包含一组窗口的Winform应用。其中使用了与Jossef Goldberg的一篇关于“Wpf应用程序内存泄露”文章中相同的方法。甚至我会直接把相同的例子和事件处理函数应用到我的Winform App中。
windbgjava的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于、windbgjava的信息别忘了在本站进行查找喔。
发布于:2022-11-26,除非注明,否则均为
原创文章,转载请注明出处。