程序的非正常跳转
来源:互联网 发布:淘宝买手现场是真的吗 编辑:程序博客网 时间:2024/04/19 17:30
我们一般在程序中执行的跳转可以通过goto、while、for、if等来实现。但是这些跳转都局限在函数内部,也就是说是一种“non-local goto”,不能在执行环境中进行任意的跳转。幸运的是绝大多数编译器还支持另外两个函数:setjmp和longjmp。原型如下:
int setjmp( jmp_bufenv );
void longjmp( jmp_bufenv, int value );
setjmp保存当前执行环境下的栈。根据具体的情况,函数的返回值有两种情况。第一种情况:函数保存当前执行环境下的栈时,其返回值为0。第二种情况:函数的返回值由longjmp的第二个参数决定。然而,如果longjmp的第二个参数为0时,函数的返回值是1。
longjmp用setjmp保存下来的栈,恢复程序在执行到setjmp时的状态,然后程序的执行路径直接跳到setjmp之后。注意:setjmp任然被执行,但是返回值将由longjmp的第二个参数来决定。
下面的代码是摘录自MSDN的一个例子程序,简要的说明了这两个函数的用法。
/* FPRESET.C: This program uses signal to setup a
*routine for handling floating-point errors.
*/
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
#include <stdlib.h>
#include <float.h>
#include <math.h>
#include <string.h>
jmp_buf mark; /* Address for long jump to jumpto */
int fperr; /* Global errornumber */
void __cdecl fphandler( int sig, int num); /* Prototypes */
void fpcheck( void );
void main( void )
{
doublen1, n2, r;
intjmpret;
/*Unmask all floating-point exceptions. */
_control87( 0, _MCW_EM );
/*Set up floating-point error handler. The compiler
*will generate a warning because it expects
*signal-handling functions to take only one argument.
*/
if( signal( SIGFPE, fphandler ) == SIG_ERR )
{
fprintf(stderr, "Couldn't set SIGFPE/n" );
abort(); }
/*Save stack environment for return in case of error. First
*time through, jmpret is 0, so true conditional is executed.
*If an error occurs, jmpret will be set to -1 and false
*conditional will be executed.
*/
jmpret= setjmp( mark );
if(jmpret == 0 )
{
printf("Test for invalid operation - " );
printf("enter two numbers: " );
scanf("%lf %lf", &n1, &n2 );
r= n1 / n2;
/*This won't be reached if error occurs. */
printf("/n/n%4.3g / %4.3g = %4.3g/n", n1, n2, r );
r= n1 * n2;
/*This won't be reached if error occurs. */
printf("/n/n%4.3g * %4.3g = %4.3g/n", n1, n2, r );
}
else
fpcheck();
}
/* fphandler handles SIGFPE (floating-pointerror) interrupt. Note
*that this prototype accepts two arguments and that the
*prototype for signal in the run-time library expects a signal
*handler to have only one argument.
*
*The second argument in this signal handler allows processing of
*_FPE_INVALID, _FPE_OVERFLOW, _FPE_UNDERFLOW, and
*_FPE_ZERODIVIDE, all of which are Microsoft-specific symbols
*that augment the information provided by SIGFPE. The compiler
*will generate a warning, which is harmless and expected.
*/
void fphandler( int sig, int num )
{
/*Set global for outside check since we don't want
*to do I/O in the handler.
*/
fperr = num;
/*Initialize floating-point package. */
_fpreset();
/*Restore calling environment and jump back to setjmp. Return
*-1 so that setjmp will return false for conditional test.
*/
longjmp( mark, 0 );
}
void fpcheck( void )
{
char fpstr[30];
switch( fperr )
{
case _FPE_INVALID:
strcpy( fpstr, "Invalid number" );
break;
case _FPE_OVERFLOW:
strcpy( fpstr, "Overflow" );
break;
case _FPE_UNDERFLOW:
strcpy( fpstr, "Underflow" );
break;
case _FPE_ZERODIVIDE:
strcpy( fpstr, "Divide by zero" );
break;
default:
strcpy( fpstr, "Other floating point error" );
break;
}
printf( "Error %d: %s/n", fperr, fpstr );
}
- 程序的非正常跳转
- 实现非正常程序流的可用机制
- vim 的非正常关闭
- Activity的非正常销毁
- Delphi刷新托盘,去掉非正常退出的程序的托盘图标
- Delphi刷新托盘,去掉非正常退出的程序的托盘图标
- 在Eclipse下没有异常非正常终止的程序运行
- 分页不能正常跳转的问题
- 检查非正常断开的tcp连接
- 检测非正常断开的TCP连接
- 处理java非正常的线程终止
- 检查非正常断开的tcp连接
- 非正常关闭服务器导致的
- 虚拟机非正常关闭的解决方案
- setjmp与longjmp相结合,实现程序的非本地的跳转
- main返回值非0表示程序未正常退出
- Linux笔记 程序非正常退出报错 Segmenttation fault
- 微信小程序页面跳转事件绑定/冒泡,非冒泡事件
- 把两个向量相加后,一定要把W值复制为1,否则所有空间集合含义全部失效!
- 感恩节后的“黑色星期五”
- 随感
- 四招助你拿下面试
- [转帖]惠普笔记本Win7激活方法
- 程序的非正常跳转
- 饱饱的火锅
- MyEclipse 6.5 GA 下载 + 汉化方法 + 序列号
- POJ 1753
- 类多继承及包含练习(c++primer plus)
- 泡泡网 前有古人后有来者! "胶水"处理器回顾
- 开发的系统终于测试完成
- oracle基础入门教材
- 写注册页面时使用的expression(css的行为)