Linux系统编程_7_进程环境之setjmp和longjmp函数

2023-11-03 20:32

本文主要是介绍Linux系统编程_7_进程环境之setjmp和longjmp函数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

大家都知道C语言中goto关键字可以用来跳转,但你知道它的跳转范围是什么吗?

goto语句只能在当前函数内不跳转,不能实现跨函数跳转;

为实现这一目的,Linux中引入了setjmp和longjmp,这两个函数对于处理发生深层嵌套函数调用中的出错情况非常有用。


函数声明:

#include <setjmp.h>

int setjmp(jmp_buf env); //env是jmp_buf类型,一般定义为全局变量

void longjmp(jmp_buf env, int val);   //val将成为调用setjmp返回的值


使用方法:

  在希望跳回的位置处写setjmp(jmpbuf);函数返回0;

  然后再程序后面可能出现错误的位置处写longjmp(jmpbf, 1) ,这会调用setjmp使其返回1;当然,可以有多个longjmp,如fun1中写longjmp(jmpbuf, 1),fun2中写longjmp(jmpbuf, 2); 则通过测试setjmp的返回值就可以判断造成返回的longjmp在哪一个函数里。

实例:

#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>static int st_var1;
int g_var;
volatile vol_var;
jmp_buf buf;static void fun1(int, int, int);
static void fun2();static void fun1(int i, int j, int k)
{printf("In Fun1!!\n");printf("st_var1=%d, st_var2=%d, g_var=%d, vol_var=%d, auto_var=%d, reg_var=%d\n",st_var1, k, g_var, vol_var, i, j);fun2();return ;
}static void fun2()
{printf("In Fun2!!\n");longjmp(buf, 1);return ;
}int main()
{int auto_var;register int reg_var;static int st_var2;printf("Start of main!!\n");st_var1 = 9, st_var2 = 10, g_var = 11, vol_var = 12, auto_var = 13, reg_var = 14;                                                                         //调用longjmp后会再次跳到这里,此时可以判断setjmp的返回值if(setjmp(buf) != 0){printf("After longjmp:\n");printf("st_var1=%d, st_var2=%d, g_var=%d, vol_var=%d, auto_var=%d, reg_var=%d\n",st_var1, st_var2, g_var, vol_var, auto_var, reg_var);exit(0);}fun1(auto_var, reg_var, st_var2);printf("End of main!!\n");/*Never print*/return 0;
}

调用main函数后,函数的栈如下如所示:


main函数中调用了setjmp,后面的longjmp函数的调用会抛弃原来栈的结构,调用longjmp后:


    这时,我们就要考虑,当longjmp函数返回到main函数时,自动变量、寄存器变量等能否恢复到原先的值呢?这个问题的答案是"不确定"

在上面的实例中,我们唯一能确定的是全局变量、静态变量、volatile定义的变量可以保持原值。


这篇关于Linux系统编程_7_进程环境之setjmp和longjmp函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/340712

相关文章

Linux系统性能检测命令详解

《Linux系统性能检测命令详解》本文介绍了Linux系统常用的监控命令(如top、vmstat、iostat、htop等)及其参数功能,涵盖进程状态、内存使用、磁盘I/O、系统负载等多维度资源监控,... 目录toppsuptimevmstatIOStatiotopslabtophtopdstatnmon

Javaee多线程之进程和线程之间的区别和联系(最新整理)

《Javaee多线程之进程和线程之间的区别和联系(最新整理)》进程是资源分配单位,线程是调度执行单位,共享资源更高效,创建线程五种方式:继承Thread、Runnable接口、匿名类、lambda,r... 目录进程和线程进程线程进程和线程的区别创建线程的五种写法继承Thread,重写run实现Runnab

在Linux中改变echo输出颜色的实现方法

《在Linux中改变echo输出颜色的实现方法》在Linux系统的命令行环境下,为了使输出信息更加清晰、突出,便于用户快速识别和区分不同类型的信息,常常需要改变echo命令的输出颜色,所以本文给大家介... 目python录在linux中改变echo输出颜色的方法技术背景实现步骤使用ANSI转义码使用tpu

linux hostname设置全过程

《linuxhostname设置全过程》:本文主要介绍linuxhostname设置全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录查询hostname设置步骤其它相关点hostid/etc/hostsEDChina编程A工具license破解注意事项总结以RHE

MySQL 中的 CAST 函数详解及常见用法

《MySQL中的CAST函数详解及常见用法》CAST函数是MySQL中用于数据类型转换的重要函数,它允许你将一个值从一种数据类型转换为另一种数据类型,本文给大家介绍MySQL中的CAST... 目录mysql 中的 CAST 函数详解一、基本语法二、支持的数据类型三、常见用法示例1. 字符串转数字2. 数字

Python内置函数之classmethod函数使用详解

《Python内置函数之classmethod函数使用详解》:本文主要介绍Python内置函数之classmethod函数使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 类方法定义与基本语法2. 类方法 vs 实例方法 vs 静态方法3. 核心特性与用法(1编程客

Python函数作用域示例详解

《Python函数作用域示例详解》本文介绍了Python中的LEGB作用域规则,详细解析了变量查找的四个层级,通过具体代码示例,展示了各层级的变量访问规则和特性,对python函数作用域相关知识感兴趣... 目录一、LEGB 规则二、作用域实例2.1 局部作用域(Local)2.2 闭包作用域(Enclos

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

Java进程异常故障定位及排查过程

《Java进程异常故障定位及排查过程》:本文主要介绍Java进程异常故障定位及排查过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、故障发现与初步判断1. 监控系统告警2. 日志初步分析二、核心排查工具与步骤1. 进程状态检查2. CPU 飙升问题3. 内存

Linux中压缩、网络传输与系统监控工具的使用完整指南

《Linux中压缩、网络传输与系统监控工具的使用完整指南》在Linux系统管理中,压缩与传输工具是数据备份和远程协作的桥梁,而系统监控工具则是保障服务器稳定运行的眼睛,下面小编就来和大家详细介绍一下它... 目录引言一、压缩与解压:数据存储与传输的优化核心1. zip/unzip:通用压缩格式的便捷操作2.