我正在尝试使用setjmp/longjmp做一些简单的事情:要求用户多次按Enter键,如果用户插入其他内容,它将使用longjmp重新启动进程.
我正在使用计数器来检查它是否有效,此计数器在启动时为0,但是当使用longjmp时,计数器将重新启动为1.
#include <stdio.h>
#include <setjmp.h>
jmp_buf buffer;
char inputBuffer[512];
void handle_interrupt(int signal) {
longjmp(buffer, 0);
}
int main(int argc, const char * argv[]) {
int counter = 0;
counter = setjmp(buffer); // Save the initial state.
printf("Counter: %d\n", counter);
printf("\nWelcome in the jump game, press enter (nothing else!): \n");
while (fgets(inputBuffer, sizeof(inputBuffer), stdin)) {
if (*inputBuffer == '\n') { // If user press Enter
counter++;
printf("%d\n\n", counter);
printf("Again: \n");
} else {
handle_interrupt(0);
}
}
}
Run Code Online (Sandbox Code Playgroud)
pc3:Assignement 3 …Run Code Online (Sandbox Code Playgroud) 我正在尝试修复其他人编写的代码中的错误,并且我试图在 gdb 中逐步了解发生了什么。但是我点击的其中一行是对 longjmp() 的调用,在该行点击“next”后,gdb 会继续正常执行,而不是中断正在执行的下一个源代码行。如果我在 longjmp() 行上尝试“step”,则会发生类似的继续。是否有任何 gdb 命令可以用来在 longjmp() 之后执行的下一个源代码行中断?
有这么简单的C代码
#include <stdio.h>
#include <setjmp.h>
void Com_Error(int);
jmp_buf abortframe;
int main() {
if (setjmp (abortframe)){
printf("abortframe!\n");
return 0;
}
Com_Error(0);
printf("main end\n");
return 0;
}
void Com_Error(int code) {
// ...
longjmp (abortframe, code);
//...
}
Run Code Online (Sandbox Code Playgroud)
我越来越:
中止帧!
我的问题是为什么它会打印abortframe!if we pass 0(NOT ) ,因此不应该满足true条件,所以没有打印字符串?if (setjmp (abortframe)){...}abortframe!
我使用sigsetjmp和siglongjmp编写了一个分段错误处理程序.一旦它进入信号处理程序,我调用siglongjmp,以便跳过错误的指令.
问题是,我再次想要导致SIGSEGV并转到相同的处理程序,但现在sigsetjmp将返回1.
如何重置sigsetjmp?
这是我的代码:
#include <stdio.h>
#include <memory.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <signal.h>
#include <setjmp.h>
sigjmp_buf env, env1;
void SIGSEGV_handler(int signal)
{
printf("Segmentation fault caught\n");
siglongjmp(env, 1);
}
int main()
{
void * allocation;
size_t size;
static int devZerofd = -1;
struct sigaction sa, sa1;
sa.sa_handler=(void*)SIGSEGV_handler;
sigaction(SIGSEGV, &sa, NULL);
if ( devZerofd == -1 ) {
devZerofd = open("/dev/zero", O_RDWR);
if ( devZerofd < 0 )
perror("open() on /dev/zero failed");
}
allocation = …Run Code Online (Sandbox Code Playgroud) 我正在阅读CSAPP,关于setjmp和的章节longjmp,并遇到以下代码片段:
int rc;
switch(setjmp(buf));
if (rc == 0)
foo();
else if (rc == 1)
printf("sth.");
else if (rc == 2)
printf("sth. other");
...
Run Code Online (Sandbox Code Playgroud)
switch语句让我很困惑,有人可以为我解释一下C中switch语句的用法吗?
PS:这实际上是CSAPP(第二版)的错误,作者通过switch-case在第三版中使用正常语句来解决这个问题.谢谢大家.
我不明白为什么在函数中middleFunc(),entry_point(arg)在if ( setjmp(middle) )语句中调用时会出现分段错误.
#include <stdio.h>
#include <setjmp.h>
jmp_buf start,middle,end;
void finalFunc(void *v)
{
printf("hello\n");
return ;
}
void middleFunc(void (*entry_point)(void *), void *arg)
{
//just debug : this does not cause segmentation fault
entry_point(arg);
if ( setjmp(middle) ){
//this casues the segmentation fault
entry_point(arg);
//once the entry point (finalFunc) is executed go to jmp_buffer end
longjmp(end,1);
}
else {
longjmp(start,1);
}
}
int main(){
if (setjmp(end)){
//exit since finalFunc has been executed
return …Run Code Online (Sandbox Code Playgroud) 我创建了一个使用 RDP(递归下降解析器)的计算器来解析和评估数学表达式“例如:5 cos(30) -5 (3+5)”。问题是我还尝试包含像“config”这样的命令,它可以让用户配置角度单位(Gra、Rad、Deg)。而这里我发现了代码设计的问题。
调用堆栈的简化示例:
int main()
{
parseexpr()
{
parseterm()
{
parsefactor()
{
parsecommand() or parsefct() or parsenumber();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在当用户输入“config”命令时。我想让他配置计算器(配置位于 .txt 文件内),然后跳回“main()”(他会被要求再次输入表达式),因为通过调用返回会出现问题堆栈,因为我需要一个返回值,而“parsecommand()”无法返回。
我的问题是如何清理调用堆栈,以便我可以通过“goto”语句直接返回到 main ?
我有一个function()电话anotherFunction().在里面anotherFunction(),有一个if语句,当满足时返回if并且不返回main().你怎么做到这一点?谢谢.
我想了解 setjmp / longjmp 的工作原理,因此我创建了一个示例程序,其中例程 A 打印偶数,例程 B 打印奇数,并且它们使用 longjmp 相互跳转:
#include <setjmp.h>
#include <stdio.h>
#define COUNTER_BEGIN 0
#define COUNTER_END 6
void routineA( jmp_buf* pEnvA, jmp_buf* pEnvB );
void routineB( jmp_buf* pEnvA, jmp_buf* pEnvB );
int main() {
const char message[] = "main [ &envA=0x^%016lx &envB=0x^%016lx ] -- %s\n";
jmp_buf envA;
jmp_buf envB;
fprintf( stdout, message, &envA, &envB,
"Started; Before calling routineA" );
routineA( &envA, &envB );
fprintf( stdout, message, &envA, &envB,
"After routineA returned; Exiting" );
return 0;
} …Run Code Online (Sandbox Code Playgroud)