2013-07-23 28 views
1

我正在寫下面的代碼,將能夠更改函數調用的堆棧。但它總是在printf上運行到段錯誤。我使用程序集調試了代碼,堆棧已成功切換。它是printf語句創建segfault並且不確定原因。任何人有任何線索我應該看更多的方向?更改堆棧的C程序的動態

謝謝。

char stack[4000000*4]; 

void foo(int ad) { 
    int i = 100; 
    int sum = i*i + ad; 
    printf("stack changed to %X\n", stack); 
} 

/* in this example, foo (and its decendents) live on a new stack */ 
void change_stack(void *newstack) { 
    void *ctx[5]; // Jump buffer for setjmp/longjmp. 
    if (0 == __builtin_longjmp(ctx)) { 
     ctx[2] = newstack; // switch stack 
     __builtin_longjmp(ctx, 1);/* here stack is switched */ 
    } else { 
    /* now live on new stack, can we pass parameters now ? */ 
    int ad = 20; 
    foo(ad); 
    } 
} 

int main (int argc, char** argv) 
{ 
    int i = 10; 
    change_stack(stack); 
    printf("return, %d\n", i); 
    return 0; 
} 

回答

2

您切換堆棧而不復制舊的內容。當change_stack返回時,結果未定義(例如,它可能跳轉到地址NULL,導致段錯誤)。而且,像局部變量這樣的東西也是未定義的。另外,(假設我們在這裏說的是x86),堆棧指針在按下時遞減。由於您分配的新堆棧指針是您的stack數組的基地址(即最低地址),因此任何推動都會將指針減少到此數組的外部,也可能導致段錯誤。

+0

感謝您的回覆。是的,發現段落錯誤來自第二個註釋中的原因。我需要使用最高的地址。首先請注意,通過幀指針訪問變量是很好的。 –

+0

您的後一點是正確的,因爲變量是通過幀指針訪問的。但是,該幀存儲在堆棧中,因此幀指針仍然指向舊的堆棧空間。 –