标签: setjmp

使用longjmp/setjmp进行C错误处理有哪些"好"的方法?

我必须将C用于一个项目,我正在考虑使用longjmp/setjmp错误处理,因为我认为在一个中心位置处理错误要比返回代码容易得多.如果有一些关于如何做到这一点的线索,我将不胜感激.

如果发生任何此类错误,我特别关注正确完成资源清理.

另外,我如何处理导致多线程程序使用它们的错误?

更好的是,是否有一些C库已经存在以进行错误/异常处理?

c error-handling longjmp setjmp

20
推荐指数
4
解决办法
9926
查看次数

为什么volatile适用于setjmp/longjmp

在调用longjmp()之后,如果自调用setjmp()以来它们的值可能已更改,则不应访问非易失性限定的本地对象.在这种情况下,它们的值被认为是不确定的,访问它们是未定义的行为.

现在我的问题是为什么在这种情况下挥发性工作?不会改变那个volatile变量仍然无法使用longjmp吗?例如,longjmp在下面给出的示例中将如何正常工作?当代码在longjmp之后返回setjmp时,local_var的值不是2而不是1吗?

void some_function()
{
  volatile int local_var = 1;

  setjmp( buf );
  local_var = 2;
  longjmp( buf, 1 );
}
Run Code Online (Sandbox Code Playgroud)

c linux x86 gcc setjmp

20
推荐指数
3
解决办法
3497
查看次数

C++异常的成本和setjmp/longjmp

我编写了一个测试来测量带有线程的C++异常的成本.

#include <cstdlib>
#include <iostream>
#include <vector>
#include <thread>

static const int N = 100000;

static void doSomething(int& n)
{
    --n;
    throw 1;
}

static void throwManyManyTimes()
{
    int n = N;
    while (n)
    {
        try
        {
            doSomething(n);
        }
        catch (int n)
        {
            switch (n)
            {
            case 1:
                continue;
            default:
                std::cout << "error" << std::endl;
                std::exit(EXIT_FAILURE);
            }
        }
    }
}

int main(void)
{
    int nCPUs = std::thread::hardware_concurrency();
    std::vector<std::thread> threads(nCPUs);
    for (int i = 0; i < nCPUs; ++i)
    {
        threads[i] …
Run Code Online (Sandbox Code Playgroud)

c c++ exception setjmp

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

如何(计算)C++中的goto和longjmp?

我通常不会编写C++代码,但我的一个奇怪的comp sci朋友厌倦了查看我精彩的FORTRAN程序并挑战我用C++重写其中一个,因为他更喜欢我的C++代码.(我们在这里投入资金.)确切的术语是它需要在现代C++编译器中进行编译.也许他讨厌一个好的conio.h - 我不知道.

现在我意识到在C++中有很好的写作方式,但是我想通过尽可能使我的C++版本成为FORTRAN-esque来获得个人胜利.对于奖励积分,当我转换代码时,这可能会节省一些时间和精力.

所以!这带我进入以下相关查询:

在gotos:

  1. 你是如何工作的?
  2. 对C++中的gotos有什么限制?
  3. 有关范围的任何担忧?(我将尽可能地尝试全局范围,但你永远不会知道.)
  4. 如果我使用GCC扩展转到void指针数组,是否有任何关于未定义行为的新问题等?


在longjmp上:

  1. 你如何安全地使用longjmp?
  2. C++中对longjmps的约束是什么?
  3. 它的作用范围是什么?
  4. 有什么特别的时刻,看起来longjmp应该是安全的,但实际上并不是我应该注意的吗?
  5. 如何使用longjmp模拟计算的goto?
  6. 如果我的程序中只有一个函数,那么使用longjmp over goto有什么明显的好处吗?

现在我的主要关注点是为此计算goto.看起来我可能会使用longjmp来完成这项工作,因为void指针数组不是C++标准的一部分,而是GCC特定的扩展.

c++ goto longjmp language-extension setjmp

12
推荐指数
2
解决办法
2915
查看次数

关于setjmp/longjmp

我正在调查setjmp/longjmp,发现setjmp保存了诸如指令指针,堆栈指针等寄存器......

但是我不知道的是,在调用setjmplongjmp之间,不能修改线程堆栈中的数据本身.在这种情况下,不会longjmp不能按预期工作.

为了说清楚,例如,当longjmp恢复堆栈指针时,说现在堆栈指针所指向的内存中的数据与调用setjmp时的数据不同.这会发生吗?如果发生这种情况,我们不是有麻烦吗?

另外,语句的意思是" 在调用setjmp()例程的例程返回后,可能不会调用longjmp()例程. "

c linux x86 setjmp

11
推荐指数
2
解决办法
8641
查看次数

究竟什么"程序状态"setjmp保存?

我已经读过传入的jmp_buf变量中的setjmp"保存程序状态",但是我还没有找到任何关于它究竟是什么的描述.它是否复制了所有应用程序的内存?只是寄存器?堆栈?

c longjmp setjmp

9
推荐指数
2
解决办法
1547
查看次数

宏地狱:与setjmp/sigsetjmp无关的平台指针

我正在编写多平台代码,需要使用指向setjmp/sigsetjmp的指针.通常情况就是如此简单

#include <setjmp.h>
void * sigsetjmp_p = sigsetjmp;
Run Code Online (Sandbox Code Playgroud)

但是,ISO和POSIX声明setjmp/sigsetjmp可以定义为宏,事实上我的linux框就是这种情况.以下摘录自/usr/include/setjmp.h:

# define sigsetjmp(env, savemask)       __sigsetjmp (env, savemask)
Run Code Online (Sandbox Code Playgroud)

问题是,由于我没有传递参数sigsetjmp,宏不会扩展,并且sigsetjmp在libc中没有定义普通符号.我希望能够使用一些宏"黑魔法"来提取"__sigsetjmp"名称,但到目前为止我已经失败了.

另一种选择是__sigsetjmp直接使用 ,但这意味着检查每个支持平台的扩展,我不想这样做(因此这个问题的原因).

PS:我讨厌宏.

注意:

我需要它的原因有点模糊,但为了简化它,我想说我想用它进行指针比较.

#include <setjmp.h>
int equals_sigsetjmp(void *p)
{
 void * sigsetjmp_p =  sigsetjmp;
 return p == sigsetjmp_p;
}
Run Code Online (Sandbox Code Playgroud)

编辑:

是的是的.我知道我不应该指望指向sigsetjmp它,因为它甚至可能不是某些平台上的函数,但这并不能解决我的问题.

在实践中,我所知道的所有平台都将其作为一个功能实现.

我可以应对这样一个事实:在几年内,我遇到了一个sigsetjump不适合某个平台的案例.但我不想应对的是通过每个支持的平台并检查setjmp.h宏定义,这是我现在唯一的选择.

我很欣赏标准的参考,但我希望得到一个实际的答案而不是纯粹的答案.

c macros iso posix setjmp

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

在'setjmp'之后我是否必须调用'longjmp'

在该手册页longjmpsetjmp,有这样一行:

如果调用setjmp()之前longjmp()调用的函数被调用,则行为未定义.

这是否意味着我实际上必须在调用longjmp的函数setjmp或嵌套函数中的某个地方调用?或者根本不打电话可以吗?

c setjmp

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

setjmp和longjmp - 用例子理解

我知道setjmp和longjmp的定义.setjmp将环境存储在堆栈上下文中,另一个恢复.

但我认为我的某些方面缺乏某种理解.有人可以借助好的例子来解释我,我如何保证,如何保存以及如何恢复它?

我看到jmp_buf中有很多CPU寄存器.但我怎么保证它恢复了?

请帮我用简洁的例子来解释.我用谷歌搜索并提到堆栈溢出的其他问题,但没有一个给出明确的例子.

非常感谢提前.

PS:它应该仅来自Linux/Unix上下文.

unix linux longjmp setjmp

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

不一致的警告:变量可能被'longjmp'或'vfork'破坏

我大多说服自己,我遇到了一些g ++ 4.8.3错误,但我想我会首先问这个列表,因为我对setjmp/longjmp的经验很少.我将我的代码简化为以下foo.cxx:

#include <setjmp.h>
#include <string.h>

// Changing MyStruct to be just a single int makes the compiler happy.
struct MyStruct
{
    int a;
    int b;
};

// Setting MyType to int makes the compiler happy.
#ifdef USE_STRUCT
typedef MyStruct MyType;
#elif USE_INT
typedef int MyType;
#endif

void SomeFunc(MyType val)
{
}

static void static_func(MyType val)
{
    SomeFunc(val);
}

int main(int argc, char **argv)
{
    jmp_buf env;
    if (setjmp(env))
    {
        return 1;
    }

    MyType val;
#ifdef USE_STRUCT
    val.a = …
Run Code Online (Sandbox Code Playgroud)

c++ longjmp setjmp g++4.8

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

标签 统计

setjmp ×10

c ×7

longjmp ×5

c++ ×3

linux ×3

x86 ×2

error-handling ×1

exception ×1

g++4.8 ×1

gcc ×1

goto ×1

iso ×1

language-extension ×1

macros ×1

posix ×1

unix ×1