- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有这个学校项目,它是关于使用 setjmp 和 longjmp 进行不精确计算的。该程序启动一个计时器,该计时器将向信号处理程序发出信号。
在计时器到期之前,有一些迭代计算(出于演示目的,只是一个没有任何用处的循环)。在此循环的开头有一个 setjmp 调用,在信号处理程序中有一个 longjmp 调用。这基本上会强制循环停止中间计算并在它调用 longjmp 的地方运行信号处理程序。
我遇到的问题是,每当计算部分很短时,我似乎相当一致地出现段错误,但是当计算部分很长时(内部循环有很多迭代),它运行得很好(没有遇到段错误)。显然,段错误一定发生在该计算部分周围的区域,但我无法弄清楚它是从哪里来的,因为调试会像使用 print 语句一样改变事物。
这是我的代码:
#include <iostream>
#include <signal.h>
#include <sys/time.h>
#include <setjmp.h>
#include <errno.h>
#include <stdlib.h>
jmp_buf env;
static void usr_timer_tick(int signal)
{
if(signal == SIGALRM)
{
longjmp(env, 1);
}
}
/*Program Description
* This program first sets up the timer to signal usr_timer_tick
* every 1 second on the SIGALRM signal. It then proceeds to do an iterated calculation three times.
* An infinite loop calls setjmp and when 0 is returned, continues doing
* a calculation on temp. After an iteration is complete, the result of
* the iteration is saved into finalResult after blocking SIGALRM to
* make the saving of the result atomic.
*
* Once the signal handler(usr_timer_tick) is triggered, it calls longjmp which forces
* setjmp to return a non-zero value, which causes the main function to break out
* of the infinite loop and start a new calculation...this is done a total of 3
* times for demonstration purposes.
*/
int main(int argc, char **argv)
{
//init timer using setitimer..real mode
int which = ITIMER_REAL;
struct itimerval value;
struct sigaction sact;
sigset_t newmask, oldmask;
sigemptyset( &newmask );
sigemptyset( &oldmask );
sigaddset(&newmask, SIGALRM);
sact.sa_flags = 0;
sact.sa_handler = usr_timer_tick;
sigaction( SIGALRM, &sact, NULL );
// value.it_interval.tv_sec = 0; /* One second */
// value.it_interval.tv_usec = 0;
// value.it_value.tv_sec = 1; /* One second */
// value.it_value.tv_usec = 0;
//
// setitimer(which, &value, NULL);
double finalResult = 0;
int loopcount = 0;
double tempResult = 0;
for(int j = 0; j < 10; j++)
{
loopcount = 0;
std::cout << "Run " << j << " begin loop "
<< loopcount << "\n";
if(setjmp(env) == 0)
{ //timer not hit yet
//sigprocmask(SIG_BLOCK, &newmask, NULL);
value.it_interval.tv_sec = 0; /* One second */
value.it_interval.tv_usec = 0;
value.it_value.tv_sec = 1; /* One second */
value.it_value.tv_usec = 0;
setitimer(which, &value, NULL);
//sigprocmask(SIG_SETMASK, &oldmask, NULL);
for(;;)
{
//Do some random calculations
for(int i = 0; i < 1; i++)
{
tempResult = tempResult + .001;
}
//block signal from arriving and save to finalResult
if(sigprocmask(SIG_BLOCK, &newmask, NULL) < 0) exit(-1);
finalResult = tempResult;
std::cout << "Run " << j << " complete loop "
<< loopcount << " result = " << finalResult<< "\n";
loopcount++;
if(sigprocmask(SIG_SETMASK, &oldmask, NULL)< 0) exit(errno);
}
}
else
{
//timer signal arrived, print the final result and get out of loop
std::cout << "***Run " << j << " killed on loop "
<< loopcount << " result = "<< finalResult << "\n";
sigprocmask(SIG_SETMASK, &oldmask, NULL);
//break;
}
}
return 0;
}
我知道你们中的一些人可能不同意在信号处理程序中使用 longjmp,但这是我的教授所说的那样做。另外,应该注意的是,我在调用 longjmp 后解除了对 SIGALRM 的阻塞(参见 main 的 else 语句)。
查看 dmesg 我得到:
[121395.233842] cppapplication_[17397]:
segfault at 2 ip b74656f6 sp bfbb5abc
error 6 in libc-2.12.1.so[b743b000+157000
]
最佳答案
您不能使用“longjmp”从定时器等异步事件中退出。它仅用于保存和恢复由普通调用约定保存的寄存器和堆栈指针。
旁注:考虑在局部变量上使用 volatile
关键字,如 7.13.2.1 中所指定:
All accessible objects have values, and all other components of the abstract machine have state, as of the time the
longjmp
function was called, except that the values of objects of automatic storage duration that are local to the function containing the invocation of the correspondingsetjmp
macro that do not have volatile-qualified type and have been changed between thesetjmp
invocation andlongjmp
call are indeterminate.
关于c++ - 使用 setjmp longjmp 时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5490038/
有没有办法使用 setjmp 来实现多任务处理?和 longjmp职能 最佳答案 这是所谓的用户空间上下文切换的一种形式。 这是可能的,但很容易出错,特别是如果您使用 setjmp 和 longjmp
我想在 Linux 环境中实现 POSIX 兼容的微线程。基本思路如下: 使用描述的技术 here , 为每个纤程分配新的栈空间。 使用 setitimer,创建将以固定时间间隔发送信号的计时器。此计
ISO/IEC 9899:1999 7.13.1.1 The setjmp macro Environmental limits 4 An invocation of the setjmp macro
我一直在尝试追踪我的代码(使用 setjmp)中的间歇性崩溃错误,并将其缩小为:在使用/O2 编译时显示,使用/O2/Oy- 消失,即仅显示省略帧指针。 http://msdn.microsoft.c
通常 setjmp 和 longjmp 不关心调用栈——函数只是保存和恢复寄存器。 我想使用 setjmp 和 longjmp 以便保留调用堆栈,然后在不同的执行上下文中恢复 EnableFeatur
下面的代码无法正常工作。谁能指出原因 #define STACK_SIZE 1524 static void mt_allocate_stack(struct thread_struct *mythr
一段代码在这里 jmp_buf mark; int Sub_Func() { int be_modify, jmpret; be_modify = 0; jmp
我的问题针对的是 setjmp/longjmp 关于局部变量的行为。 示例代码: jmp_buf env; void abc() { int error; ... if(error)
我正在尝试为 C OSX Carbon 多线程 应用程序安装“崩溃处理程序”。在 Windows 上,我可以轻松使用简单高效的 __try{} __except{} SEH of Windows效果很
我必须使用 setjmp/longjmp 实现用户级线程库作为作业。这是我写的代码: #include #include #include #include #include #includ
这个问题来自 SetJmp/LongJmp: Why is this throwing a segfault? 当我使用 Debug模式运行代码时,它确实按预期崩溃了。但是如果我使用 release
我不明白为什么在函数 middleFunc() 中,当 entry_point(arg) 在 if ( setjmp(中间) ) 语句。 #include #include
为什么 setjmp 不保存堆栈? 考虑以下代码: #include jmp_buf Buf; jmp_buf Buf2; void MyFunction() { for(int i = 0
#include #include #include #include static jmp_buf env_alrm; static void sig_alarm(int signo) {
在不久前的blog post中,Scott Vokes使用C函数setjmp和longjmp描述了与lua实现协程相关的技术问题: The main limitation of Lua corouti
在jpeglib ,必须使用 setjmp/longjmp 来实现自定义错误处理。 有很多资源说 setjmp/longjmp 不能很好地与 c++ 配合使用(例如 this question 中的答
我的问题针对的是 setjmp/longjmp 关于局部变量的行为。 示例代码: jmp_buf env; void abc() { int error; ... if(error)
我试图理解以下代码中的 setjmp: http://androidxref.com/4.2.2_r1/xref/frameworks/base/core/jni/android/graphics/Y
我正在调查setjmp/longjmp,发现setjmp 保存指令指针、堆栈指针等寄存器... 然而,我在这里没有得到的是,在调用 setjmp 和 longjmp 之间,不能修改线程本身堆栈中的数据
在 Why volatile works for setjmp/longjmp , 用户 greggo评论: Actually modern C compilers do need to know t
我是一名优秀的程序员,十分优秀!