__try,__except无法捕捉的异常

ninibay 2013-05-27 11:19:40
char pBuf[2] = {0};
__try
{
sprintf_s(pBuf,2,"abcd");
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
printf("excption\n");
}

这块代码在release版本下直接崩溃,为嘛SHE无法捕捉异常?怎么样才能让其捕捉到该异常?
...全文
629 18 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 15 楼 ninibay 的回复:
[quote=引用 14 楼 adlay 的回复:] [quote=引用 10 楼 ninibay 的回复:] [quote=引用 9 楼 adlay 的回复:] 不是不能捕获异常, 是你的程序根本就没有产生异常. sprintf_s 函数里面有对参数做检查, 发现错误后直接调用报告错误的函数来报告错误了, 没有进入异常处理的流程.
程序都崩溃了应该有异常的吧。。。?[/quote] 何谓崩溃? 弹了出错的对话框? 这个概念太模糊了, 只要程序没有按照设计的退出都可以叫崩溃, 崩溃不一定是由异常引起的. sprintf 并不会因为访问内存越界而产生异常的, 它在访问内存之前会先检查参数. 而你这个情况, 就算是访问了越界的内存, 也不会产生异常. 只是会产生未定义的行为, 可能覆盖到其它的全局变量而已. [/quote] 这个貌似有点牵强了~ 局部数组写穿了会覆盖全局变量? 堆栈那边我不大懂。。。[/quote] 当然有可能。
ninibay 2013-05-28
  • 打赏
  • 举报
回复
基本找到答案了~ http://hi.baidu.com/combojiang/item/c0018d02426dede5ff240d9d
ninibay 2013-05-27
  • 打赏
  • 举报
回复
问题的重点是异常无法捕获,sprintf_s只是产生异常的工具
ninibay 2013-05-27
  • 打赏
  • 举报
回复
引用 9 楼 adlay 的回复:
不是不能捕获异常, 是你的程序根本就没有产生异常. sprintf_s 函数里面有对参数做检查, 发现错误后直接调用报告错误的函数来报告错误了, 没有进入异常处理的流程.
程序都崩溃了应该有异常的吧。。。?
www_adintr_com 2013-05-27
  • 打赏
  • 举报
回复
不是不能捕获异常, 是你的程序根本就没有产生异常. sprintf_s 函数里面有对参数做检查, 发现错误后直接调用报告错误的函数来报告错误了, 没有进入异常处理的流程.
ninibay 2013-05-27
  • 打赏
  • 举报
回复
引用 6 楼 akirya 的回复:
不能捕获越界是很正常的
不是有个EXCEPTION_ARRAY_BOUNDS_EXCEEDED对应数组越界吗?
ninibay 2013-05-27
  • 打赏
  • 举报
回复
引用 4 楼 VisualEleven 的回复:
sprintf_s(pBuf,2,"abcd"); 用法错了吧 sprintf_s(pBuf, "%s", "abcd");
sprintf_s(pBuf,2,"abcd"); 这样写没问题 不过sprintf_s(pBuf, "%s", "abcd");是个好习惯
  • 打赏
  • 举报
回复
不能捕获越界是很正常的
Eleven 2013-05-27
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <stdlib.h>
#include <crtdbg.h>  // For _CrtSetReportMode

void myInvalidParameterHandler(const wchar_t* expression,
							   const wchar_t* function, 
							   const wchar_t* file, 
							   unsigned int line, 
							   uintptr_t pReserved)
{
	printf("Invalid parameter detected in function");
}


int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	_set_invalid_parameter_handler(myInvalidParameterHandler);

	_CrtSetReportMode(_CRT_ASSERT, 0);


	char pBuf[2] = {0};
	sprintf_s(pBuf, "%s", "abcd");

	return 0;
}
Eleven 2013-05-27
  • 打赏
  • 举报
回复
sprintf_s(pBuf,2,"abcd"); 用法错了吧 sprintf_s(pBuf, "%s", "abcd");
ninibay 2013-05-27
  • 打赏
  • 举报
回复
在线等待中。。
ninibay 2013-05-27
  • 打赏
  • 举报
回复
是__except(EXCEPTION_EXECUTE_HANDLER)
ouyh12345 2013-05-27
  • 打赏
  • 举报
回复
不是__catch?
www_adintr_com 2013-05-27
  • 打赏
  • 举报
回复
哦, 不会哈 你以为你的 char pBuf[2] = {0}; 是在全局定义的. 局部变量越界肯定不会覆盖到全局变量, 但是通常也不会产生异常, 只是可能覆盖到其它的局部变量, 函数的返回地址等等, 可能造成以后的代码运行异常, 但是覆盖写入的时候不会异常.
ninibay 2013-05-27
  • 打赏
  • 举报
回复
引用 14 楼 adlay 的回复:
[quote=引用 10 楼 ninibay 的回复:] [quote=引用 9 楼 adlay 的回复:] 不是不能捕获异常, 是你的程序根本就没有产生异常. sprintf_s 函数里面有对参数做检查, 发现错误后直接调用报告错误的函数来报告错误了, 没有进入异常处理的流程.
程序都崩溃了应该有异常的吧。。。?[/quote] 何谓崩溃? 弹了出错的对话框? 这个概念太模糊了, 只要程序没有按照设计的退出都可以叫崩溃, 崩溃不一定是由异常引起的. sprintf 并不会因为访问内存越界而产生异常的, 它在访问内存之前会先检查参数. 而你这个情况, 就算是访问了越界的内存, 也不会产生异常. 只是会产生未定义的行为, 可能覆盖到其它的全局变量而已. [/quote] 这个貌似有点牵强了~ 局部数组写穿了会覆盖全局变量? 堆栈那边我不大懂。。。
www_adintr_com 2013-05-27
  • 打赏
  • 举报
回复
引用 10 楼 ninibay 的回复:
[quote=引用 9 楼 adlay 的回复:] 不是不能捕获异常, 是你的程序根本就没有产生异常. sprintf_s 函数里面有对参数做检查, 发现错误后直接调用报告错误的函数来报告错误了, 没有进入异常处理的流程.
程序都崩溃了应该有异常的吧。。。?[/quote] 何谓崩溃? 弹了出错的对话框? 这个概念太模糊了, 只要程序没有按照设计的退出都可以叫崩溃, 崩溃不一定是由异常引起的. sprintf 并不会因为访问内存越界而产生异常的, 它在访问内存之前会先检查参数. 而你这个情况, 就算是访问了越界的内存, 也不会产生异常. 只是会产生未定义的行为, 可能覆盖到其它的全局变量而已. 你要测试产生异常, 用下面这个代码来产生吧:

		char *p = (char*)0xF0000000;
		p[0] = 1;
ninibay 2013-05-27
  • 打赏
  • 举报
回复
没太看明白这个问题的答案在哪里,能具体指出来吗?
赵4老师 2013-05-27
  • 打赏
  • 举报
回复
try-except Statement Microsoft Specific —> The try-except statement is a Microsoft extension to the C and C++ languages that enables 32-bit target applications to gain control when events that normally terminate program execution occur. Such events are called exceptions, and the mechanism that deals with exceptions is called structured exception handling. For related information, see the try-finally statement. For more information on structured exception handling in general, see Exception Handling Topics (SEH). Exceptions can be either hardware-based or software-based. Even when applications cannot completely recover from hardware or software exceptions, structured exception handling makes it possible to display error information and trap the internal state of the application to help diagnose the problem. This is especially useful for intermittent problems that cannot be reproduced easily. Note Structured exception handling works with Win32 for both C and C++ source files. However, it is not specifically designed for C++. You can ensure that your code is more portable by using C++ exception handling. Also, C++ exception handling is more flexible, in that it can handle exceptions of any type. For C++ programs, it is recommended that you use the new C++ exception-handling mechanism (try, catch, and throw statements). try-except-statement : __try compound-statement __except ( expression ) compound-statement The compound statement after the __try clause is the body or guarded section. The compound statement after the __except clause is the exception handler. The handler specifies a set of actions to be taken if an exception is raised during execution of the body of the guarded section. Execution proceeds as follows: The guarded section is executed. If no exception occurs during execution of the guarded section, execution continues at the statement after the __except clause. If an exception occurs during execution of the guarded section or in any routine the guarded section calls, the __except expression is evaluated and the value determines how the exception is handled. There are three values: EXCEPTION_CONTINUE_EXECUTION (–1) Exception is dismissed. Continue execution at the point where the exception occurred. EXCEPTION_CONTINUE_SEARCH (0) Exception is not recognized. Continue to search up the stack for a handler, first for containing try-except statements, then for handlers with the next highest precedence. EXCEPTION_EXECUTE_HANDLER (1) Exception is recognized. Transfer control to the exception handler by executing the __except compound statement, then continue execution at the assembly instruction that was executing when the exception was raised. Because the __except expression is evaluated as a C expression, it is limited to a single value, the conditional-expression operator, or the comma operator. If more extensive processing is required, the expression can call a routine that returns one of the three values listed above. Each application can have its own exception handler. The __except expression executes in the scope of the __try body. This means it has access to any local variables declared there. It is illegal to jump into a __try statement, but legal to jump out of one. The exception handler is not called if a process is killed in the middle of executing a try-except statement. Structured Exception Handling Intrinsic Functions The structured exception handling feature provides two intrinsics that are available for use with the try-except statement. These are _exception_code and _exception_info. The intrinsic function _exception_code returns the code (a 32-bit integer) of the exception. The intrinsic function _exception_info returns a pointer to a structure containing additional information about the exception. Through this pointer, you can access the machine state that existed at the time of a hardware exception. The structure is as follows: struct exception_pointers { EXCEPTION_RECORD *ExceptionRecord, CONTEXT *ContextRecord } The pointer types _EXCEPTION_RECORD and _CONTEXT are defined in the include file EXCPT.H. You can use the _exception_code function within the exception handler. However, you can use _exception_info only within the exception filter. The information it points to is generally on the stack and is wiped out when control is transferred to the exception handler. The intrinsic function _abnormal_termination is available within a termination handler. It returns 0 if the body of the try-finally statement terminates sequentially. In all other cases, it returns 1. END Microsoft Specific Example // Example of try-except and try-finally statements #include "stdio.h" void main() { int* p = 0x00000000; // pointer to NULL puts("hello"); try{ puts("in try"); try{ puts("in try"); *p = 13; // causes an access violation exception; }__finally{ puts("in finally"); } }__except(puts("in filter"), 1){ puts("in except"); } puts("world"); } This is the output from the example, with commentary added on the right: hello in try //fall into try in try //fall into nested try in filter //execute filter; returns 1 so accept in finally //unwind nested finally in except //transfer control to selected handler world //flow out of handler

15,473

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧