函数调用约定Powerpc vs Intel

时间:2012-05-17 06:04:23

标签: c segmentation-fault stack-trace intel powerpc

我需要以下信息:

powerpc和intel处理器在调用函数时如何分配堆栈? - 在什么基础上确定每种情况下的堆栈大小,即powerpc和intel x86处理器 - 参数和返回地址存储在堆栈中。

基本上我需要在每种情况下堆叠布局。

我的情况是我的程序在intel机器中崩溃(分段故障)并且在powerpc上正常运行。我找到了崩溃的原因,代码片段如下:

int function_a(int a)
{
   int local_var = 1;
   int ret_var;

   ret_var = function_b(&local_var);

}

int function_b (int* local_var_in_calld_fn)
{

   while (some_condition)
   {
      *local_var_in_calld_fn = some_computed_value; /* Cause of crash */
      local_var_in_calld_fn++; 
   }
   return something;
}

某个值会在“可能”处于堆叠状态的地址上更新,从而导致崩溃。 代码完全没有在位置崩溃,但是当在x86机器上退出此函数后,在gdb中调试时崩溃了。

我怀疑它破坏了堆栈,但它没有崩溃在powerpc上。

由于

2 个答案:

答案 0 :(得分:3)

这里有明显的堆栈溢出。
function_a获取指向单个int的指针,递增(因此它指向堆栈中的其他位置),然后写入。

堆栈溢出的结果非常难以预测。它取决于调用约定,还取决于编译器决策,例如变量排序和内联,这些决策没有以任何方式标准化。

我不想弄清楚为什么它会在一个案件中而不是在另一个案件中崩溃 更好的解决方法。

答案 1 :(得分:0)

操作系统负责分配堆栈,而不是处理器。 PowerPC处理器甚至不知道或不关心堆栈; “堆栈指针”是惯例r1,一个完全正常的寄存器,但这是平台相关的。你还没有说明这个平台正在运行。

在这种情况下,崩溃是由行local_var_in_calld_fn++;引起的,这是未定义的行为(也许你的意思是*local_var_in_calld_fn++;)。问题是“为什么未定义的行为不会崩溃?”答案很简单:

未定义的行为未定义,因此绝对可能发生任何,包括不会崩溃。

除此之外,最简单的解释为什么它不会崩溃是因为some_condition在PPC上评估为false(因为它是单核因此锁定争用较少所以你还没有注意到崩溃)。

我还可以提出一个不会崩溃的案例:

  • 在这个特定的平台上,堆栈成长(我不确定是否有任何常见的做法)。这意味着写入*local_var_in_calld_fn可以有效地增加堆栈并可能破坏function_b()的堆栈,但不会覆盖任何调用者的堆栈。
  • function_b()是一个“叶子函数”(即不进行任何函数调用),因此LR不需要保存在堆栈中。这意味着写入*local_var_in_calld_fn并不会破坏回复地址。
  • some_condition很快就会变得虚假,以至于你没有用完堆栈。