当前位置: 首页 > news >正文

新网站怎么快速收录必做免费下载大都会

新网站怎么快速收录必做,免费下载大都会,烟台公司网站定制,哈尔滨市建设工程信息网官网首页VC常用功能开发汇总#xff08;专栏文章列表#xff0c;欢迎订阅#xff0c;持续更新...#xff09;https://blog.csdn.net/chenlycly/article/details/124272585C软件异常排查从入门到精通系列教程#xff08;专栏文章列表#xff0c;欢迎订阅#xff0c;持续更新...常用功能开发汇总专栏文章列表欢迎订阅持续更新...https://blog.csdn.net/chenlycly/article/details/124272585C软件异常排查从入门到精通系列教程专栏文章列表欢迎订阅持续更新...https://blog.csdn.net/chenlycly/article/details/125529931C软件分析工具从入门到精通案例集锦专栏文章持续更新中...https://blog.csdn.net/chenlycly/article/details/131405795C/C基础与进阶专栏文章持续更新中...https://blog.csdn.net/chenlycly/category_11931267.html       之前我们详细介绍了如何使用内存泄漏检测工具Visual Leak Detector简称VLD以及相关配置本文我们从源码的角度去讲述VLD的内存检测原理及实现感兴趣的朋友可以来了解一下。 1、Visual C内置的CRT Debug Heap工作原理 我们先来看一下Visual C内置的CRT Debug Heap运行时调试堆是如何工作的。Visual C内置的工具CRT Debug Heap工作原来很简单。比如在使用Debug版的接口动态申请内存时会在内存块的头中记录分配该内存的文件名及行号。当程序退出时CRT会在main()函数返回之后做一些清理工作这个时候来检查调试堆内存如果仍然有内存没有被释放则一定是存在内存泄漏。从这些没有被释放的内存块的头中就可以获得文件名及行号。 关于Visual C内置的CRT Debug Heap调试堆的详细说明可以参看微软官网的说明 CRT debug heap detailshttps://learn.microsoft.com/en-us/cpp/c-runtime-library/crt-debug-heap-details?viewmsvc-170       这种静态的方法可以检测出内存泄漏及其泄漏点的文件名和行号但是并不知道泄漏究竟是如何发生的并不知道该内存分配语句是如何被执行到的。要想了解这些就必须要对程序的内存分配过程进行动态跟踪。Visual Leak Detector就是这样做的。它在每次内存分配时将其上下文记录下来当程序退出时对于检测到的内存泄漏查找其记录下来的上下文信息并将其转换成报告输出。 2、VLD内存泄漏检测原理 Visual Leak Detector的代码是开源的有详尽的文档及注释对于想深入了解堆内存管理以及内存泄漏排查机制的朋友是个不错的选择。关于如何使用Visual Leak Detector可以参见我之前写的文章 如何使用Visual Leak Detector排查内存泄漏问题https://blog.csdn.net/chenlycly/article/details/133041372        Visual Leak Detector检测内存泄漏的大体步骤如下 1首先在初始化注册一个钩子函数 2然后在内存分配时该钩子函数被调用以记录下当时的现场 3最后检查堆内存分配链表以确定是 否存在内存泄漏并将泄漏内存的现场转换成可读的形式输出。 2.1、初始化 Visual Leak Detector要记录每一次的内存分配而它是如何监视内存分配的呢Windows提供了分配钩子allocation hooks来监视调试堆内存的分配。它是一个用户定义的回调函数在每次从调试堆分配内存之前被调用。在初始化时Visual Leak Detector使用_CrtSetAllocHook注册这个钩子函数这样就可以监视从此之后所有的堆内存分配了。 如何保证在Visual Leak Detector初始化之前没有堆内存分配呢全局变量是在程序启动时就初始化的如果将Visual Leak Detector作为一个全局变量就可以随程序一起启动。但是C/C并没有约定全局变量之间的初始化顺序如果其它全局变量的构造函数中有堆内存分配则可能无法检测到。Visual Leak Detector使用了C/C提供的#pragma init_seg来在某种程度上减少其它全局变量在其之前初始化的概率。 根据#pragma init_seg的定义全局变量的初始化分三个阶段 1首先是compiler段一般c语言的运行时库在这个时候初始化 2然后是lib段一般用于第三方的类库的初始化等 3最后是user段大部分的初始化都在这个阶段进行。 Visual Leak Detector将其初始化设置在compiler段从而使得它在绝大多数全局变量和几乎所有的用户定义的全局变量之前初始化。 2.2、记录分配的内存 一个分配钩子函数需要具有如下的形式 int YourAllocHook( int allocType, void *userData, size_t size, int blockType, long requestNumber, const unsignedchar *filename, int lineNumber); 就像前面说的它在Visual Leak Detector初始化时被注册每次从调试堆分配内存之前被调用。这个函数需要处理的事情是记录下此时的调用堆栈和此次堆内存分配的唯一标识requestNumber。 得到当前的堆栈的二进制表示并不是一件很复杂的事情但是因为不同体系结构、不同编译器、不同的函数调用约定所产生的堆栈内容略有不同要解释堆栈并得到整个函数调用过程略显复杂。不过windows提供一个StackWalk64函数可以获得堆栈的内容。StackWalk64的声明如下 BOOL IMAGEAPI StackWalk64([in] DWORD MachineType,[in] HANDLE hProcess,[in] HANDLE hThread,[in, out] LPSTACKFRAME64 StackFrame,[in, out] PVOID ContextRecord,[in, optional] PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,[in, optional] PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,[in, optional] PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,[in, optional] PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress ); STACKFRAME64结构表示了堆栈中的一个frame该结构体定义如下 typedef struct _tagSTACKFRAME64 {ADDRESS64 AddrPC;ADDRESS64 AddrReturn;ADDRESS64 AddrFrame;ADDRESS64 AddrStack;ADDRESS64 AddrBStore;PVOID FuncTableEntry;DWORD64 Params[4];BOOL Far;BOOL Virtual;DWORD64 Reserved[3];KDHELP64 KdHelp; } STACKFRAME64, *LPSTACKFRAME64; 给出初始的STACKFRAME64反复调用该函数便可以得到内存分配点的调用堆栈了。 // Walk the stack. while (count _VLD_maxtraceframes) {count;if (!pStackWalk64(architecture, m_process, m_thread, frame, context,NULL, pSymFunctionTableAccess64, pSymGetModuleBase64, NULL)) {// Couldnt trace back through any more frames.break;}if (frame.AddrFrame.Offset 0) {// End of stack.break;}// Push this frames program counter onto the provided CallStack.callstack-push_back((DWORD_PTR)frame.AddrPC.Offset); } 那么如何得到初始的STACKFRAME64结构呢在STACKFRAME64结构中其他的信息都比较容易获得而当前的程序计数器(EIP)在x86体系结构中无法通过软件的方法直接读取。Visual Leak Detector使用了一种方法来获得当前的程序计数器。首先它调用一个函数则这个函数的返回地址就是当前的程序计数器而函数的返回地址可以很容易的从堆栈中拿到。下面是Visual Leak Detector获得当前程序计数器的程序 #if defined(_M_IX86) || defined(_M_X64)#pragma auto_inline(off)DWORD_PTR VisualLeakDetector::getprogramcounterx86x64 () {DWORD_PTR programcounter;__asm mov AXREG, [BPREG SIZEOFPTR] // Get the return address out of the current stack frame__asm mov [programcounter], AXREG    // Put the return address into the variable well returnreturn programcounter; }#pragma auto_inline(on)#endif // defined(_M_IX86) || defined(_M_X64) 得到了调用堆栈自然要记录下来。Visual Leak Detector使用一个类似map的数据结构来记录该信息。这样可以方便的从requestNumber查找到其调用堆栈。分配钩子函数的allocType参数表示此次堆内存分配的类型包括_HOOK_ALLOC, _HOOK_REALLOC, 和 _HOOK_FREE下面代码是Visual Leak Detector对各种情况的处理 switch (type) {case _HOOK_ALLOC:visualleakdetector.hookmalloc(request);break;case _HOOK_FREE:visualleakdetector.hookfree(pdata);break;case _HOOK_REALLOC:visualleakdetector.hookrealloc(pdata, request);break;default:visualleakdetector.report(WARNING: Visual Leak Detector: in allochook(): Unhandled allocation type (%d)./n, type);break; } 这里hookmalloc()函数得到当前堆栈并将当前堆栈与requestNumber加入到类似map的数据结构中。hookfree()函数从类似map的数据结构中删除该信息。hookrealloc()函数依次调用了hookfree()和hookmalloc()。 2.3、检测内存泄露 前面提到了Visual C内置的内存泄漏检测工具的工作原理。与该原理相同因为全局变量以构造的相反顺序析构在Visual Leak Detector析构时几乎所有的其他变量都已经析构此时如果仍然有未释放之堆内存则必为内存泄漏。 分配的堆内存是通过一个链表来组织的检查内存泄漏则是检查此链表。但是windows没有提供方法来访问这个链表。Visual Leak Detector使用了一个小技巧来得到它。首先在堆上申请一块临时内存则该内存的地址可以转换成指向一个_CrtMemBlockHeader结构在此结构中就可以获得这个链表。代码如下 char *pheap newchar; _CrtMemBlockHeader *pheader pHdr(pheap)-pBlockHeaderNext; delete pheap; 其中pheader则为链表首指针。 2.4、生成检测报告 前面讲了Visual Leak Detector如何检测、记录内存泄漏及其其调用堆栈。但如果要这个信息对程序员有用的话必须转换成可读的形式。Visual Leak Detector使用SymGetLineFromAddr64()及SymFromAddr()生成可读的报告。 // Iterate through each frame in the call stack. for (frame 0; frame callstack-size(); frame) {// Try to get the source file and line number associated with// this program counter address.if (pSymGetLineFromAddr64(m_process, (*callstack)[frame], displacement, sourceinfo)) {...}// Try to get the name of the function containing this program// counter address.if (pSymFromAddr(m_process, (*callstack)[frame], displacement64, pfunctioninfo)) {functionname pfunctioninfo-Name;}else {functionname (Function name unavailable);}... } 概括讲来Visual Leak Detector的工作分为3步 1首先在初始化注册一个钩子函数 2然后在内存分配时该钩子函数被调用以记录下当时的现场 3最后检查堆内存分配链表以确定是否存在内存泄漏并将泄漏内存的现场转换成可读的形式输出。 详细的细节有兴趣的读者可以阅读Visual Leak Detector的源代码。  比如我故意写了一段内存泄漏的代码Visual Leak Detector生成的报告内容如下 Detected memory leaks! Dumping objects - d:\testmemleak\testmemleak\testmemleak.cpp(70) : {343} normal block at 0x00C1E3A8, 2000 bytes long.  Data:                 CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD  Object dump complete. WARNING: Visual Leak Detector detected memory leaks! ---------- Block 13 at 0x00C1E3A8: 2000 bytes ----------   Leak Hash: 0xDA40455C, Count: 1, Total 2000 bytes Call Stack (TID 4356):     mfc100ud.dll!0x7B874750()     d:\testmemleak\testmemleak\testmemleak.cpp (70): TestMemLeak.exe!CTestMemLeakApp::InitInstance() 0x18 bytes     mfc100ud.dll!0x7BBA94F4()     f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\appmodul.cpp (26): TestMemLeak.exe!wWinMain()     f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (547): TestMemLeak.exe!__tmainCRTStartup() 0x2C bytes     f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (371): TestMemLeak.exe!wWinMainCRTStartup()     KERNEL32.DLL!BaseThreadInitThunk() 0x19 bytes     ntdll.dll!RtlGetAppContainerNamedObjectPath() 0x11E bytes     ntdll.dll!RtlGetAppContainerNamedObjectPath() 0xEE bytes   Data:     CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........     CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........     CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........     CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........     CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........     CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........     CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........     CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........     CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........     CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........     CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........     CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........     CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........     CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........     CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........     CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........ Visual Leak Detector detected 1 memory leak (2036 bytes). Largest number used: 14610 bytes. Total allocations: 16326 bytes. Visual Leak Detector is now exiting. 从上面生成的报告信息可以看出发生内存泄漏的代码文件testmemleak.cpp及行号(70) 能看到详细的函数调用堆栈还能看到发生泄漏的内存中的数据。一般通过这些信息我们可以快速地定位问题。 3、总结 在使用上Visual Leak Detector简单方便结果报告一目了然。在原理上Visual Leak Detector针对内存泄漏问题的特点可谓对症下药——内存泄漏不是不容易发现吗那就每次内存分配是都给记录下来程序退出时算总账内存泄漏现象出现时不是已时过境迁并非当时泄漏点的现场了吗那就把现场也记录下来清清楚楚的告诉使用者那块泄漏的内存就是在如何一个调用过程中泄漏掉的。
http://www.pierceye.com/news/109488/

相关文章:

  • 网站专题设计稿用vue做商城网站常用的js
  • 怎么在免费空间里面做网站深圳英文站seo
  • 学风建设网站版块如何用visual studio做网站
  • 山东响应式网站设置字体颜色的网站
  • 美容院网站建设西安有关做网站的公司有哪些
  • 湛江做网站设计公司网络推广网站培训班
  • 大型网站建立萝岗微信网站建设
  • 门户网站建设发展趋势官网网站怎么创建
  • 企业网站如何做自然搜索phpcms 网站转移
  • 站内优化怎么做建设设计网站
  • 如何建设机器人教育网站上海有名的网络公司
  • 网站二级目录做网站淄博网站建设 很乱
  • 常州做网站企业海口网站开发建设
  • 做php网站用什么软件开发wordpress页面图片轮播图
  • 做网站页面大小多大8上的信息课做网站作业
  • 自己做微网站创欧科技 网站建设
  • 网站设计师大学学什么专业北京燕华工程建设有限公司网站
  • 广州专业网站建设企业wordpress 数据库修改
  • 淮南装饰公司网站建设seo 网站树
  • 设计素材下载网站网络营销课程设计报告
  • 安庆公司做网站搜索引擎收录提交入口
  • 城固网站建设wordpress主题谁的最好
  • 国外建站企业北京鑫创网站建设
  • 网站做视频wordpress插件手动升级
  • wordpress收不到网站没有收款接口网站怎么做收款
  • 信阳做网站推广用tornado做网站
  • 网站开发与数据库ppt成都优化网站建设
  • 毕业设计静态网站建设选题依据企业网络营销的优势
  • 网站图片动态换名网站充值支付宝收款怎么做
  • 蜘蛛网是个什么网站做特卖的购物网站