标签: setjmp

longjmp(buffer,0)不返回0

我正在尝试使用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)

c longjmp setjmp

2
推荐指数
1
解决办法
118
查看次数

如何在gdb中单步执行longjmp

我正在尝试修复其他人编写的代码中的错误,并且我试图在 gdb 中逐步了解发生了什么。但是我点击的其中一行是对 longjmp() 的调用,在该行点击“next”后,gdb 会继续正常执行,而不是中断正在执行的下一个源代码行。如果我在 longjmp() 行上尝试“step”,则会发生类似的继续。是否有任何 gdb 命令可以用来在 longjmp() 之后执行的下一个源代码行中断?

c gdb setjmp

2
推荐指数
1
解决办法
919
查看次数

使用 setjmp 和 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!

c setjmp

2
推荐指数
1
解决办法
77
查看次数

我们可以重置sigsetjmp再次返回"0"(重置sigsetjmp)吗?

我使用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)

c linux signals setjmp

1
推荐指数
1
解决办法
1386
查看次数

C中的特殊switch语句

我正在阅读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在第三版中使用正常语句来解决这个问题.谢谢大家.

c switch-statement setjmp

1
推荐指数
1
解决办法
161
查看次数

为什么在setjmp()中调用函数会发生分段错误?

我不明白为什么在函数中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)

c multithreading segmentation-fault fiber setjmp

1
推荐指数
1
解决办法
153
查看次数

如何释放C中的调用堆栈?

我创建了一个使用 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 ?

c stack callstack goto setjmp

1
推荐指数
1
解决办法
148
查看次数

如何返回main而不是调用它的函数

我有一个function()电话anotherFunction().在里面anotherFunction(),有一个if语句,当满足时返回if并且不返回main().你怎么做到这一点?谢谢.

c function control-flow setjmp

0
推荐指数
1
解决办法
108
查看次数

setjmp / longjmp 没有跳到我认为应该跳的地方

我想了解 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)

c setjmp

0
推荐指数
1
解决办法
134
查看次数