注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Tsecer的回音岛

Tsecer的博客

 
 
 

日志

 
 

sigaltstack函数对线程连续信号堆栈处理  

2011-05-06 22:10:42|  分类: Linux内核 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

一、问题

对于多线程的时候,为了避免堆栈被破坏之后堆栈已经不再有效,从而发生二次内存访问违例异常。有些任务会在自己的系统启动的时候注册一个信号专门使用的异常信号,但是对于多线程的时候,理论上就可以应该为每个线程都分配一个私有的信号堆栈。但是这样对于系统内存消耗会特别多,可能系统根本负担不起。有些系统一般是让所有的线程共享一个信号堆栈,这个时候当一个进程(其中有多个线程)获得了多个信号的时候这个系统的堆栈是如何处理的呢?

二、API及实现

sys32_sigaltstack(const stack_t32 __user *uss, stack_t32 __user *uoss)

if (uss) {
  if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
   return -EFAULT;
  err |= __get_user(ss_sp, &uss->ss_sp);
  err |= __get_user(kss.ss_size, &uss->ss_size);
  err |= __get_user(kss.ss_flags, &uss->ss_flags);
  if (err)
   return -EFAULT;
  kss.ss_sp = (void __user *) ss_sp;
 }

这里有一个我们不太关注的ss_flags标志,这个可选的值为SS_DISABLE or SS_ONSTACK,也就是可以使能,也可以禁用该功能。正如该函数的API中说明的,当我们当前正在堆栈处理函数中,这个系统调用时会失败的:

do_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, unsigned long sp)
  if (on_sig_stack(sp))
   goto out;

…………

if (ss_flags != SS_DISABLE && ss_flags != SS_ONSTACK && ss_flags != 0)
   goto out;

  if (ss_flags == SS_DISABLE) {
   ss_size = 0;
   ss_sp = NULL;
  } else {
   error = -ENOMEM;
   if (ss_size < MINSIGSTKSZ)
    goto out;
  }

  current->sas_ss_sp = (unsigned long) ss_sp;
  current->sas_ss_size = ss_size;

三、当异常发生时

handle_signal-->>setup_rt_frame-->>ia32_setup_rt_frame-->>get_sigframe

 /* This is the X/Open sanctioned signal stack switching.  */
 if (ka->sa.sa_flags & SA_ONSTACK) {
  if (sas_ss_flags(sp) == 0)
   sp = current->sas_ss_sp + current->sas_ss_size;
 }

/* True if we are on the alternate signal stack.  */

static inline int on_sig_stack(unsigned long sp)
{
 return (sp - current->sas_ss_sp < current->sas_ss_size);
}

static inline int sas_ss_flags(unsigned long sp)
{
 return (current->sas_ss_size == 0 ? SS_DISABLE
  : on_sig_stack(sp) ? SS_ONSTACK : 0);

}

这里做个一个特殊处理。就是判断如果当前系统的堆栈已经在 替换堆栈 中,那么我们就需要在当前堆栈的基础上继续执行。但是从这个结构可以看到,其中的sas_ss_size都是一个线程内部的直接变量,所以不同的线程不会相互影响。这个带来的效果就是如果所有的线程共享同一个堆栈,那么不同的线程信号处理函数会相互干扰,但是同一个线程却不会受到影响

  评论这张
 
阅读(1248)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017