1

我需要以下信息:

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

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

我有一种情况,我的程序在英特尔机器中崩溃(分段错误)并且在 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 上崩溃。

谢谢

4

2 回答 2

3

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

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

我不会纠结于为什么它在一种情况下崩溃而不是在另一种情况下崩溃。
最好只是修复它。

于 2012-05-17T06:37:08.033 回答
0

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

在这种情况下,崩溃是由 line 引起的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很快就会变成假,以至于你不会用完堆栈。
于 2012-06-11T19:27:41.647 回答