c 写的程序经常会有空指针引用,遇到这种情况,程序会被系统强行终止,客户会看到一个该死的对话框,里面写着神秘的诅咒代码。
为了不被使用程序的用户咒骂,应该温和的给予温柔的提示,并保存当前的工作内容,
于是我开发了这个小工具代码,允许你像 Java 一样的抓住异常,这是程序例子:
支持多线程,支持嵌套 try
最新的代码版本
https://github.com/yanmingsohu/c-tool
头文件:
源文件:
为了不被使用程序的用户咒骂,应该温和的给予温柔的提示,并保存当前的工作内容,
于是我开发了这个小工具代码,允许你像 Java 一样的抓住异常,这是程序例子:
支持多线程,支持嵌套 try
1234567891011121314151617181920212223242526 |
#include <stdio.h>
#include <stdlib.h>
#include "exception.h"
int
main
()
{
try
{
try
{
int
*
a
=
NULL
;
*
a
=
1
;
}
catch
(
b
)
{
printf
(
"some error 2. %x
\n
"
,
b
);
}
finally
{
}
int
*
a
=
NULL
;
*
a
=
1
;
}
catch
(
a
)
{
printf
(
"some error 1. %x
\n
"
,
a
);
}
finally
printf
(
"over
\n
"
);
return
0
;
}
|
最新的代码版本
https://github.com/yanmingsohu/c-tool
头文件:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
// J.yanming 2013/7/19 yanming-sohu@sohu.com
// CatfoOD crazy code.
// 如果不需要导出 try 等关键字,则定义 NOT_EXPORT_TRY
// finally 必须出现在 catch 之后!
#ifndef _EXCEPTION_J_
#define _EXCEPTION_J_
#include <setjmp.h>
#define _MAX_EXCEPTION_DEEP_ 255
#define _MAX_THREAD_COUNT_ 255
#define _HAS_EXCEPTION_ 1
#define _NOT_EXCEPTION_ 0
#ifdef __WIN32__
#include <Windows.h>
#define THREAD_ID DWORD
#define GET_CURRENT_THREAD GetCurrentThreadId
typedef
EXCEPTION_POINTERS
*
EXCEPTION_INF
;
#else
#ifdef __linux__
#include <pthread.h>
#define THREAD_ID pthread_t
#define GET_CURRENT_THREAD pthread_self
typedef
void
*
EXCEPTION_INF
;
// ?
#else
// Other system.
#define THREAD_ID int
#define GET_CURRENT_THREAD i_dont_know
typedef
void
*
EXCEPTION_INF
;
#endif
// __linux__
#endif
// __WIN32__
typedef
struct
__THREAD_MARK
{
EXCEPTION_INF
exception_info
;
THREAD_ID
thread_id
;
int
current_exp_mark
;
jmp_buf
mark
[
_MAX_EXCEPTION_DEEP_
];
}
THREAD_MARK
;
typedef
jmp_buf
*
ExceptionMark
;
void
_init_exception
();
void
_exit_exception_deep
();
THREAD_MARK
*
_create_exception_deep
();
#define _TRY_ \
_init_exception(); \
THREAD_MARK* ___exp_mark = _create_exception_deep(); \
if (___exp_mark && \
(setjmp(___exp_mark->mark[___exp_mark->current_exp_mark]) == _NOT_EXCEPTION_) ) {
#define _CATCH_(x) \
_exit_exception_deep(___exp_mark); \
} else { \
_exit_exception_deep(___exp_mark); \
EXCEPTION_INF x = ___exp_mark->exception_info;
#define _TEND_ \
}
#ifndef NOT_EXPORT_TRY
#
define
try
_TRY_
#
define
catch
_CATCH_
#
define
finally
_TEND_
#endif
#endif
|
源文件:
// J.yanming 2013/7/19 yanming-sohu@sohu.com
// CatfoOD crazy code.
#include "exception.h"
static
THREAD_MARK
thread_mark
[
_MAX_THREAD_COUNT_
];
static
int
mark_length
=
0
;
static
int
inited
=
0
;
static
void
reclaimMemory
()
{
// 需要同步锁,防止在读取的时候修改了内存顺序
}
static
THREAD_MARK
*
findThread
()
{
THREAD_ID
tid
=
GET_CURRENT_THREAD
();
THREAD_MARK
*
tm
=
NULL
;
int
i
;
for
(
i
=
0
;
i
<
mark_length
;
++
i
)
{
if
(
thread_mark
[
i
].
thread_id
==
tid
)
{
tm
=
thread_mark
+
i
;
break
;
}
}
return
tm
;
}
static
THREAD_MARK
*
newThread
()
{
if
(
mark_length
>=
_MAX_THREAD_COUNT_
)
{
reclaimMemory
();
if
(
mark_length
>=
_MAX_THREAD_COUNT_
)
{
return
NULL
;
}
}
THREAD_ID
tid
=
GET_CURRENT_THREAD
();
THREAD_MARK
*
tm
=
&
thread_mark
[
mark_length
++
];
tm
->
thread_id
=
tid
;
return
tm
;
}
static
void
outThread
(
THREAD_MARK
*
tm
)
{
if
(
tm
)
{
tm
->
thread_id
=
0
;
}
}
#ifdef __WIN32__
static
long
WINAPI
_ExceptionGlobeFilter
(
EXCEPTION_POINTERS
*
lParam
)
{
THREAD_MARK
*
tm
=
findThread
();
if
(
tm
->
current_exp_mark
)
{
tm
->
exception_info
=
lParam
;
longjmp
(
tm
->
mark
[
tm
->
current_exp_mark
],
_HAS_EXCEPTION_
);
}
return
1
;
}
#endif
void
_init_exception
()
{
if
(
!
inited
)
{
#ifdef __WIN32__
SetUnhandledExceptionFilter
(
_ExceptionGlobeFilter
);
#endif
inited
=
1
;
}
}
THREAD_MARK
*
_create_exception_deep
()
{
THREAD_MARK
*
tm
=
findThread
();
if
(
!
tm
)
tm
=
newThread
();
if
(
!
tm
)
return
NULL
;
int
deep
=
tm
->
current_exp_mark
;
if
(
deep
>=
_MAX_EXCEPTION_DEEP_
)
{
return
NULL
;
}
else
{
tm
->
current_exp_mark
++
;
}
return
tm
;
}
void
_exit_exception_deep
(
THREAD_MARK
*
tm
)
{
if
(
tm
->
current_exp_mark
>
0
)
{
--
tm
->
current_exp_mark
;
}
else
{
outThread
(
tm
);
}
}
|