可能堆栈损坏 [英] Possible Stack Corruption

查看:191
本文介绍了可能堆栈损坏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

参照有关 GDB不见真章SIGSEGV点,

我的线程code是如下:

 无效*亚军(void *的使用)
{
 做
 {
 sem_wait(安培; X);
  ...  如果(/ *条件1检查* /)
  {
   sem_post(安培; X);
   睡眠(5);
   sem_wait(安培; X);
   如果(/ *重复检查-1;后ATLEAST5秒* /)
   {
    的printf(离开...... \\ n);
    sem_post(安培; X);
    //把出口(0);在这里解决了两难境地
    返回(NULL);
   }
  }
 sem_post(安培; X);
 }而(1);}

主要code:

  sem_t X;INT主要(无效)
{
    sem_init(安培;的x,0,1);
        ...
    的pthread_t THRID;
    在pthread_create(安培; THRID,NULL,亚军,NULL);
        ...
    在pthread_join(THRID,NULL);
    返回(0);
}


编辑:有一个出口(0)在亚军线程code,使得故障清漆


这可能是什么堆栈腐败背后的原因是什么?

GDB输出:(0xb7fe2b70是亚军线程ID)

 即将离开...
计划接收信号SIGSEGV,分割过错。
[切换主题0xb7fe2b70(LWP 2604)]
0x00000011在?? ()

Valgrind的输出:

  == == 3076线程2:
== == 3076跳转到无效地址下一行规定
== == 3076在为0x11:???
== == 3076通过0xA26CCD:克隆(clone.S:133)
== == 3076地址为0x11不stack'd,malloc分配或(最近)free'd
== == 3076
== == 3076
== == 3076过程终止与信号11的默认操作(SIGSEGV)
地址为0x11的映射区域== == 3076权限错误
== == 3076在为0x11:???
== == 3076通过0xA26CCD:克隆(clone.S:133)
== == 3076地址为0x11不stack'd,malloc分配或(最近)free'd


解决方案

写了功能,做同样的事情,在<$ C $一个新的源文件C>主您张贴在这里除了不使用在pthread_create 只是调用该函数。看看你是否可以重新独立使用线程的问题。从事物的方式看看你的信号灯应该还是在单线程环境中工作得很好。

如果这仍然失败,您将有一个更简单的调试时间了。

既然你说叫退出而不是返回没有取得它会提示你已经破坏了错误,要么是在堆栈上的返回地址时,亚军已启动。通过调用退出你不靠这个内存区域去的退出功能(如果你已经回到了pthread_exit会被称为由pthread库code,它呼吁亚军)。我认为Valgrind的输出不是100%准确 - 不是由于Valgrind的任何过错,而是因为你在哪里触发加上你正在引发错误的类型错误的地方,使这很难确定谁叫什么

一些 GCC 标记你可能感兴趣的:

  -fstack保护器,所有-Wstack保护器

警告选项不无这里的-f选项工作。

您也可以试试:

  -fno-省略帧指针

With reference to my previous question about GDB not pinpointing the SIGSEGV point,

My thread code is as follows:

void *runner(void *unused)
{
 do
 {
 sem_wait(&x);
  ...

  if(/*condition 1 check*/)
  {
   sem_post(&x);
   sleep(5);
   sem_wait(&x);
   if(/*repeat condition 1 check; after atleast 5 seconds*/)
   {
    printf("LEAVING...\n");
    sem_post(&x); 
    // putting exit(0); here resolves the dilemma
    return(NULL);  
   }
  }
 sem_post(&x);
 }while(1);

}

Main code:

sem_t x;    

int main(void)
{   
    sem_init(&x,0,1);
        ...
    pthread_t thrId;
    pthread_create(&thrId,NULL,runner,NULL);
        ...
    pthread_join(thrId,NULL);
    return(0);
}


Edit: Having an exit(0) in the runner thread code, makes the fault vanish.


What could be the reasons behind the stack corruption?

GDB Output: (0xb7fe2b70 is runner thread id)

LEAVING...
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb7fe2b70 (LWP 2604)]
0x00000011 in ?? ()

Valgrind Output:

==3076== Thread 2:
==3076== Jump to the invalid address stated on the next line
==3076==    at 0x11: ???
==3076==    by 0xA26CCD: clone (clone.S:133)
==3076==  Address 0x11 is not stack'd, malloc'd or (recently) free'd
==3076== 
==3076== 
==3076== Process terminating with default action of signal 11 (SIGSEGV)
==3076==  Bad permissions for mapped region at address 0x11
==3076==    at 0x11: ???
==3076==    by 0xA26CCD: clone (clone.S:133)
==3076==  Address 0x11 is not stack'd, malloc'd or (recently) free'd

解决方案

Write a new source file with a main function that does the same things as the main you posted here except rather than using pthread_create just call the function. See if you can recreate the issue independent of using threads. From the way things look your semaphores should still work just fine in a single threaded environment.

If this still fails you will have an easier time debugging it.

Since you said that calling exit rather than returning did not yield the error it would suggest that you have corrupted either the return address that is on the stack when runner is started. By calling exit you don't rely on this memory area to get to an exiting function (if you had returned pthread_exit would have been called by the pthread library code that had called runner). I think that the valgrind output is not 100% accurate -- not due to any fault in valgrind, but because the place where you are triggering the error coupled with the type of error you are triggering makes this very difficult to be sure who called what.

Some gcc flags you may be interested in:

-fstack-protector-all -Wstack-protector

The warning option doesn't work without the -f option here.

You may also want to try:

-fno-omit-frame-pointer

这篇关于可能堆栈损坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆