C++定义图 编译通过 solidworks运行宏崩溃崩溃

4126人阅读
程序在运行时,难免会有一些异常情况发生,特别是在条件不容许去挂调试器的时候,如何快速的定位错误的方法就显得很重要。
日志一直都是一种很重要的定位错误的方法,出得好的日志可以方便程序员快速的定位问题所在。但日志有时也显不足:
日志有时只能定位大体错误范围,却无法确认问题所在,比如程序抓到一个未知的异常。程序有时没有机会来出日志,或者能出日志的时候已经无法获得和错误相关的信息,比如程序崩溃的时候。
在日志明显不足的时候,把进程中相关数据DUMP下来分析就是一个比较实用方便的方法。很多应用都会提供这类功能,以便在程序出现问题时可以把相关的数据发给开发者,方便开发者分析问题。类似Office这样的应用都会有这个功能,当应用崩溃时会弹出对话框,提示是否发送错误相关的数据。
如何在自己程序中也添加类似的功能呢?其实这方面的代码很多的,在网上可以搜到很多,也有许多都是弄好的,只要你在自己程序中加几行代码就可以实现。我以前开发的程序就参用过BugTrap来实现这种功能。在CodeProject中有篇文章“!”,可以下载它的代码。
也可以使用WheatyExceptionReport,它的代码定义了一个WheatyExceptionReport类型的全局变量g_WheatyExceptionReport。在WheatyExceptionReport的构造函数中,代码调用SetUnhandledExceptionFilter,并且设置异常处理器为WheatyExceptionReport::WheatyUnhandledExceptionFilter。在网上可以搜到代码,只有把它加到工程中就可以使用了(针对非托管C++代码)
其实要实现这个功能并不是很难,自己也可以调用MS DbgHelp.dll中MiniDumpWriteDump来实现。自己实现的好处在于不用增加许多用不到的代码。
MiniDumpWriteDump可以导出程序内部的内存、堆栈、句柄、线程、模块等程序运行相关的信息,该函数的原型如下(具体细节参考 DbgHelp.h ):
BOOL WINAPI
MiniDumpWriteDump(
&&& IN HANDLE hProcess,
&&& IN DWORD ProcessId,
&&& IN HANDLE hFile,
&&& IN MINIDUMP_TYPE DumpType,
&&& IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL
&&& IN CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, OPTIONAL
&&& IN CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam OPTIONAL
使用这个函数我们可以自己写个比较简单的函数,在出现问题时候的Dump进程数据,再用WinDbg来分析问题所在。
1&/******************************************************************
Routine Description:&&&&&&&&
Arguments:&&&&&&&&&&&&
Remark:&&&&&&&&
*******************************************************************/
11&&&&&int&GenerateMiniDump(HANDLE
hFile, PEXCEPTION_POINTERS pExceptionPointers)
13&&&&&&&&
BOOL bOwnDumpFile&&&&=&FALSE;
14&&&&&&&&
HANDLE hDumpFile&&&&=&hF&&&&
15&&&&&&&&
MINIDUMP_EXCEPTION_INFORMATION ExpP
17&&&&&&&&
typedef BOOL (WINAPI&*&MiniDumpWriteDumpT)(&
18&&&&&&&&&&&&
19&&&&&&&&&&&&
20&&&&&&&&&&&&
21&&&&&&&&&&&&
MINIDUMP_TYPE ,
22&&&&&&&&&&&&
PMINIDUMP_EXCEPTION_INFORMATION ,
23&&&&&&&&&&&&
PMINIDUMP_USER_STREAM_INFORMATION ,
24&&&&&&&&&&&&
PMINIDUMP_CALLBACK_INFORMATION
25&&&&&&&&&&&&
27&&&&&&&&
MiniDumpWriteDumpT pfnMiniDumpWriteDump&=&NULL;
28&&&&&&&&
HMODULE hDbgHelp&=&LoadLibrary(_T(&DbgHelp.dll&));
29&&&&&&&&&if&(hDbgHelp)
30&&&&&&&&&&&&
pfnMiniDumpWriteDump&=&(MiniDumpWriteDumpT)GetProcAddress(hDbgHelp,&MiniDumpWriteDump&);
31&&&&&&&&&
32&&&&&&&&&if&(pfnMiniDumpWriteDump)
33&&&&&&&&
34&&&&&&&&&&&&&if&(hDumpFile==NULL&||&hDumpFile==INVALID_HANDLE_VALUE)
35&&&&&&&&&&&&
36&&&&&&&&&&&&&&&&
TCHAR szPath[MAX_PATH]&&&&&&&&=&{0};&
37&&&&&&&&&&&&&&&&
TCHAR szFileName[MAX_PATH]&&&&=&{0};&
38&&&&&&&&&&&&&&&&
TCHAR*&szAppName&&&&&&&&&&&&=&L&XXXXXXXXXX&;&
39&&&&&&&&&&&&&&&&
TCHAR*&szVersion&&&&&&&&&&&&=&L&v2.0&;&
40&&&&&&&&&&&&&&&&
TCHAR dwBufferSize&&&&&&&&&&&&=&MAX_PATH;&
41&&&&&&&&&&&&&&&&
SYSTEMTIME stLocalT&
43&&&&&&&&&&&&&&&&
GetLocalTime(&&stLocalTime );&
44&&&&&&&&&&&&&&&&
GetTempPath( dwBufferSize, szPath );
46&&&&&&&&&&&&&&&&
StringCchPrintf( szFileName, MAX_PATH, L&%s%s&,
szPath, szAppName );&
47&&&&&&&&&&&&&&&&
CreateDirectory( szFileName, NULL );
49&&&&&&&&&&&&&&&&
StringCchPrintf( szFileName, MAX_PATH, L&%s%s//%s-%04d%02d%02d-%02d%02d%02d-%ld-%ld.dmp&,&
50&&&&&&&&&&&&&&&&&&&&
szPath, szAppName, szVersion,&
51&&&&&&&&&&&&&&&&&&&&
stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,&
52&&&&&&&&&&&&&&&&&&&&
stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond,&
53&&&&&&&&&&&&&&&&&&&&
GetCurrentProcessId(), GetCurrentThreadId());&
54&&&&&&&&&&&&&&&&
hDumpFile&=&CreateFile(szFileName, GENERIC_READ|GENERIC_WRITE,&
55&&&&&&&&&&&&&&&&&&&&
FILE_SHARE_WRITE|FILE_SHARE_READ,&0,
CREATE_ALWAYS,&0,&0);
57&&&&&&&&&&&&&&&&
bOwnDumpFile&=&TRUE;
58&&&&&&&&&&&&
60&&&&&&&&&&&&&if&(hDumpFile!=INVALID_HANDLE_VALUE)
61&&&&&&&&&&&&
62&&&&&&&&&&&&&&&&
ExpParam.ThreadId&=&GetCurrentThreadId();&
63&&&&&&&&&&&&&&&&
ExpParam.ExceptionPointers&=&pExceptionP&
64&&&&&&&&&&&&&&&&
ExpParam.ClientPointers&=&FALSE;
66&&&&&&&&&&&&&&&&
pfnMiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),&
67&&&&&&&&&&&&&&&&&&&&
hDumpFile, MiniDumpWithDataSegs, (pExceptionPointers&?&&ExpParam
: NULL), NULL, NULL);
69&&&&&&&&&&&&&&&&&if&(bOwnDumpFile)
70&&&&&&&&&&&&&&&&&&&&
CloseHandle(hDumpFile);
71&&&&&&&&&&&&
72&&&&&&&&
73&&&&&&&&&&&&&
74&&&&&&&&&if&(hDbgHelp!=NULL)
75&&&&&&&&&&&&
FreeLibrary(hDbgHelp);
77&&&&&&&&&return&EXCEPTION_EXECUTE_HANDLER;&
参数PEXCEPTION_POINTERS pExceptionPointers可以通过两种方式取得:
1、结构化异常的__except内通过GetExceptionInformation()取得。
__except(GenerateMiniDump(hFile, GetExceptionInformation()),EXCEPTION_CONTINUE_EXECUTION)&
其实在使用GenerateMiniDump也可以不用传入LPEXCEPTION_POINTERS值,有它只是方便WinDbg使用命令.ecxr&直接显示出现问题的位置,比如在C++异常Catch中抓到一个未知的异常,这时虽然不能取得EXCEPTION_POINTERS指针,但是出现异常时的CONTEX指针已经在内存中了,只要手工找到它,同样可以知道出现异常时的环境。
使用WinDbg找异常CONTEXT位置的方法有很多,我平时使用的使用过WinDbg的搜索内存命令来找,查看WinNt.h中的x86 CONTEXT定义:
1&typedef&struct&_CONTEXT
4&&&&&//&The
flags values within this flag control the contents of
5&&&&&//&a
CONTEXT record.
7&&&&&//&If
the context record is used as an input parameter, then
8&&&&&//&for
each portion of the context record controlled by a flag
9&&&&&//&whose
value is set, it is assumed that that portion of the
10&&&&&//&context
record contains valid context. If the context record
11&&&&&//&is
being used to modify a threads context, then only that
12&&&&&//&portion
of the threads context will be modified.
14&&&&&//&If
the context record is used as an IN OUT parameter to capture
15&&&&&//&the
context of a thread, then only those portions of the thread's
16&&&&&//&context
corresponding to set flags will be returned.
18&&&&&//&The
context record is never used as an OUT only parameter.
DWORD ContextF
24&&&&&//&This
section is specified/returned if CONTEXT_DEBUG_REGISTERS is
25&&&&&//&set
in ContextFlags.& Note that CONTEXT_DEBUG_REGISTERS is NOT
26&&&&&//&included
in CONTEXT_FULL.
DWORD&& Dr0;
DWORD&& Dr1;
DWORD&& Dr2;
DWORD&& Dr3;
DWORD&& Dr6;
DWORD&& Dr7;
37&&&&&//&This
section is specified/returned if the
38&&&&&//&ContextFlags
word contians the flag CONTEXT_FLOATING_POINT.
FLOATING_SAVE_AREA FloatS
44&&&&&//&This
section is specified/returned if the
45&&&&&//&ContextFlags
word contians the flag CONTEXT_SEGMENTS.
DWORD&& SegGs;
DWORD&& SegFs;
DWORD&& SegEs;
DWORD&& SegDs;
54&&&&&//&This
section is specified/returned if the
55&&&&&//&ContextFlags
word contians the flag CONTEXT_INTEGER.
66&&&&&//&This
section is specified/returned if the
67&&&&&//&ContextFlags
word contians the flag CONTEXT_CONTROL.
DWORD&& SegCs;&&&&&&&&&&&&&&//&MUST BE SANITIZED
DWORD&& EF&&&&&&&&&&&&&//&MUST BE SANITIZED
DWORD&& SegSs;
78&&&&&//&This
section is specified/returned if the ContextFlags word
79&&&&&//&contains
the flag CONTEXT_EXTENDED_REGISTERS.
80&&&&&//&The
format and contexts are processor specific
BYTE&&& ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];
89&typedef
CONTEXT&*PCONTEXT;
其中ContextFlags的值一般都是CONTEXT_ALL,这个宏的值为0x1003f(如果是其它值也可以算出值),通过在WinDbg中搜索0x1003f就能快速找到异常CONTEXT指针值,如下:
s -d 0 L?FFFFFFFF 0x1003f,从搜索出的结果中可以比较方便的找到所要的异常CONTEXT指针值,如果找到后使用命令.cxr就可以看到异常发生时的寄存器值、堆栈等信息。
__except(GenerateMiniDump(hFile, GetExceptionInformation()),EXCEPTION_CONTINUE_EXECUTION)&
2、设置的UnhandledExceptionFilter传人的参数。
SetUnhandledExceptionFilter(UnhandledExceptionFilter);
LONG WINAPI UnhandledExceptionFilter(LPEXCEPTION_POINTERS lpExceptionInfo)
&&&&if(IsDebuggerPresent())&
&&&&&&&&return&EXCEPTION_CONTINUE_SEARCH;
&&&&return&GenerateMiniDump(hFile,lpExceptionInfo);
============================================================================
实际代码如下:
#include &DbgHelp.h&
//生产DUMP文件
int GenerateMiniDump(HANDLE hFile, PEXCEPTION_POINTERS pExceptionPointers, PWCHAR pwAppName)
BOOL bOwnDumpFile = FALSE;
HANDLE hDumpFile = hF
MINIDUMP_EXCEPTION_INFORMATION ExpP
typedef BOOL(WINAPI * MiniDumpWriteDumpT)(
MINIDUMP_TYPE,
PMINIDUMP_EXCEPTION_INFORMATION,
PMINIDUMP_USER_STREAM_INFORMATION,
PMINIDUMP_CALLBACK_INFORMATION
MiniDumpWriteDumpT pfnMiniDumpWriteDump = NULL;
HMODULE hDbgHelp = LoadLibrary(L&DbgHelp.dll&);
if (hDbgHelp)
pfnMiniDumpWriteDump = (MiniDumpWriteDumpT)GetProcAddress(hDbgHelp, &MiniDumpWriteDump&);
if (pfnMiniDumpWriteDump)
if (hDumpFile == NULL || hDumpFile == INVALID_HANDLE_VALUE)
TCHAR szPath[MAX_PATH] = { 0 };
TCHAR szFileName[MAX_PATH] = { 0 };
TCHAR* szAppName = pwAppN
TCHAR* szVersion = L&v1.0&;
TCHAR dwBufferSize = MAX_PATH;
SYSTEMTIME stLocalT
GetLocalTime(&stLocalTime);
GetTempPath(dwBufferSize, szPath);
StringCchPrintf(szFileName, MAX_PATH, L&%s%s&, szPath, szAppName);
CreateDirectory(szFileName, NULL);
StringCchPrintf(szFileName, MAX_PATH, L&%s%s//%s-%04d%02d%02d-%02d%02d%02d-%ld-%ld.dmp&,
szPath, szAppName, szVersion,
stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,
stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond,
GetCurrentProcessId(), GetCurrentThreadId());
hDumpFile = CreateFile(szFileName, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRITE | FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
bOwnDumpFile = TRUE;
OutputDebugString(szFileName);
if (hDumpFile != INVALID_HANDLE_VALUE)
ExpParam.ThreadId = GetCurrentThreadId();
ExpParam.ExceptionPointers = pExceptionP
ExpParam.ClientPointers = FALSE;
pfnMiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
hDumpFile, MiniDumpWithDataSegs, (pExceptionPointers ? &ExpParam : NULL), NULL, NULL);
if (bOwnDumpFile)
CloseHandle(hDumpFile);
if (hDbgHelp != NULL)
FreeLibrary(hDbgHelp);
return EXCEPTION_EXECUTE_HANDLER;
LONG WINAPI ExceptionFilter(LPEXCEPTION_POINTERS lpExceptionInfo)
if (IsDebuggerPresent())
return EXCEPTION_CONTINUE_SEARCH;
return GenerateMiniDump(NULL, lpExceptionInfo, L&test&);
//程序入口函数
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
lpCmdLine,
//加入崩溃dump文件功能
SetUnhandledExceptionFilter(ExceptionFilter);
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1396335次
积分:13977
积分:13977
排名:第603名
原创:29篇
转载:709篇
评论:144条
(4)(17)(5)(12)(2)(3)(17)(41)(31)(11)(8)(14)(12)(12)(6)(18)(10)(8)(17)(5)(2)(7)(7)(7)(10)(15)(23)(25)(5)(19)(9)(3)(9)(7)(10)(18)(19)(25)(13)(14)(7)(15)(36)(7)(3)(8)(17)(12)(32)(14)(4)(14)(26)(7)(15)(11)(16)(5)C/CPP系列知识 那些程序C语言可以编译通过但C++无法编译成功
Write a C program that won’t compile in C++
1) C++中在函数声明之前调用一个函数会引发错误,但是在C中有可能可以。 参考&/diegodu/p/4580292.html
下面的程序可以用gcc编译,但g++无法编译。
#include&stdio.h&
int main()
foo(); // foo() is called before its declaration/definition
printf("Hello");
编译结果:
:~/myProg/geeks4geeks/cpp$ gcc test3.c
:~/myProg/geeks4geeks/cpp$ g++ test3.c
test3.c: In function 'int main()':
test3.c:4:9: error: 'foo' was not declared in this scope
foo(); // foo() is called before its declaration/definition
2) C++中将一个非const指针指向一个const变量是非法的,但在C中是可以的。
#include &stdio.h&
int main(void)
int const j = 20;
/* The below assignment is invalid in C++, results in error
In C, the compiler *may* throw a warning, but casting is
implicitly allowed */
int *ptr = &j;
// A normal pointer points to const
printf("*ptr: %d\n", *ptr);
编译结果:
:~/myProg/geeks4geeks/cpp$ gcc test4.c
test4.c: In function 'main':
test4.c:10:16: warning: initialization discards 'const' qualifier from pointer target type [enabled by default]
int *ptr = &j;
// A normal pointer points to const
:~/myProg/geeks4geeks/cpp$ g++ test4.c
test4.c: In function 'int main()':
test4.c:10:17: error: invalid conversion from 'const int*' to 'int*' [-fpermissive]
int *ptr = &j;
// A normal pointer points to const
3) C中可以将void* 赋值给其他的指针,如int*, char*等,但是在C++中则需要显示的类型转换。
#include &stdio.h&
int main()
int *iptr = //In C++, it must be replaced with int *iptr=(int *)
编译结果:
:~/myProg/geeks4geeks/cpp$ gcc test5.c
:~/myProg/geeks4geeks/cpp$ g++ test5.c
test5.c: In function 'int main()':
test5.c:5:17: error: invalid conversion from 'void*' to 'int*' [-fpermissive]
int *iptr = //In C++, it must be replaced with int *iptr=(int *)
这也就意味着在C++中我们调用malloc时需要显示的转换类型,&int *p = (void *)malloc(sizeof(int)),而在C中不需要。
4) C++中const变量声明的同时必须赋初值,但C中不需要赋初值。
#include &stdio.h&
int main()
编译结果:
:~/myProg/geeks4geeks/cpp$ gcc test6.c
:~/myProg/geeks4geeks/cpp$ g++ test6.c
test6.c: In function 'int main()':
test6.c:4:15: error: uninitialized const 'a' [-fpermissive]
5) C++中的关键字在C中不可用,如new,delete,explicit等。
#include &stdio.h&
int main(void)
int new = 5;
// new is a keyword in C++, but not in C
printf("%d", new);
6) C++有着更加严格的类型检查。C++无法通过编译,有error,C中仅仅报warning
#include &stdio.h&
int main()
char *c = ;
printf("c = %u", c);
编译结果:
:~/myProg/geeks4geeks/cpp$ gcc test7.c
test7.c: In function 'main':
test7.c:4:15: warning: initialization makes pointer from integer without a cast [enabled by default]
char *c = ;
test7.c:5:5: warning: format '%u' expects argument of type 'unsigned int', but argument 2 has type 'char *' [-Wformat=]
printf("c = %u", c);
:~/myProg/geeks4geeks/cpp$ g++ test7.c
test7.c: In function 'int main()':
test7.c:4:15: error: invalid conversion from 'int' to 'char*' [-fpermissive]
char *c = ;
test7.c:5:23: warning: format '%u' expects argument of type 'unsigned int', but argument 2 has type 'char*' [-Wformat=]
printf("c = %u", c);
7) C++变量可以在任意位置定义,但是C中必须是一个语句块开始的地方。(gcc 中可以编译。。)
#include &stdio.h&
int main()
8) C++存在loop variable,C中不存在。
#include &stdio.h&
int main()
for(int i=0; i&5; i++)
9) C++ main函数必须返回int,C可以返回void
#include &stdio.h&
void main (int argc, char *argv[])
printf("bye\n");
编译结果:
:~/myProg/geeks4geeks/cpp$ gcc test9.c
:~/myProg/geeks4geeks/cpp$ g++ test9.c
test9.c:2:34: error: '::main' must return 'int'
void main (int argc, char *argv[])
:~/myProg/geeks4geeks/cpp$
> 本站内容系网友提交或本网编辑转载,其目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请及时与本网联系,我们将在第一时间删除内容!
http://www.geeksforgeeks.org/extern-c-in-c/
C++函数重载(function overloading),但是C++编译器是如何区分不同的函数的呢?-是通过在函数名是加些信息来区不同的函数,即所谓的Name Mangling.C++标准并没有对name mangling技术,各个编译器可以添加不同的信息.
http://www.geeksforgeeks.org/g-fact-95/
1 在C语言中,如果函数在声明之前被调用,那么编译器假设函数的返回值的类型为INT型, 所以下面的code将无法通过编译: #include &stdio.h& int main(void) { // Note that fun() is not declared ...
C/C+中的每一个常亮(every literal)都是有类型的,例如10 就是int型的,因此siziof(10)和sizeof(int)是相同的,但是字符型常亮(‘a’)在C和C++中有不同的变量类型. 在C中,‘a’被认为是int形,在C++中,‘a’被认为是char型. int main() { printf(&sizeof('V') =
这算是本系列文章的一个序吧,主要是为以后的学习做铺垫,文本分为三个部分,第一部分是对于网上一些比较旧的资料的问题的一些更正,当然我也不可能看过所有的资料,难免会有遗漏.第二部分是D语言最基本的规定,第三部分是相关的资源 一.对于一些网上旧资料上的内容不准确之处在此指出 1.D对闭包的支持不好 目前版本支持完全的闭包,所以不用担心
2.D不支持动态链接 目 ...
&Ajax构建工具箱指南&是一本面向初学者,甚至是不懂任何程序开发语言的读者的书——当然,如果读者理解XHTML.CSS.JavaScript或PHP的基本知识会更好. &Ajax构建工具箱指南&从Ajax的概念被提出到流行以来涌现的众多现实应用中,精心遴选了10个最有实用价值,而且能够实现组件化(或者说“即插即用”式)应用的实例,包 ...
用汉语编程序:太极语言解释运行程序设计(序) 快速入门: 把下面的例子程序保存输入太极 文件名就可以运行了. 比如存为文件&天&,输入太极 天就可以了 当然要先到我的网站()上下载下来太极语言解释器 1.显示(&太极&);//显示“太极” 2.整数//定义整数变量
原文地址:十 ARM9(2440)的IIC--理论知识及程序实例作者:骨Zi里德骄傲 概述 S3C2440A RISC 微处理器可以支持一个多主控IIC 总线串行接口.一条专用串行数据线(SDA)和一条专用 串行时钟线(SCL)传递连接到IIC 总线的总线主控和外设之间的信息.SDA 和SCL 线都为双向的. 多主控IIC 总线模式中,多个S3C2440A
听说嫁人要嫁程序员,钱多话少死得早.这话多半是程序员自己黑自己的.程序员是有非常特别的幽默感的一群,善于自嘲,勇于自黑,耐受力超强,很多事无可无不可,不到是不可孰不可忍不会冲冠一怒.不过,就是这么 nice 的人,也很有一些受不了的事儿.需求变化
为什么把&需求变化&排第一呢?
因为有人说:杀一个程序员不需要用枪,改三 ...求教大神:c++程序编译通过,但运行总提示停止工作。。。_百度知道c++程序每次编译通过了,但是运行时就停止工作一般是什么地方出错了呢?_百度知道

我要回帖

更多关于 vs2008编译崩溃 的文章

 

随机推荐