【发布时间】:2013-04-21 07:02:48
【问题描述】:
我正在尝试编写一个简单的用户级线程库作为我的操作系统课程的练习。作为第一步,我试图运行一个程序并跳转到离开第一个程序的函数。到目前为止的代码是这样的:
初始程序:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#define STACK_SIZE (sizeof(void *) * 512)
void proc2() //This is the function that should run as the thread.
{
int i;
for(i=0;i<30;i++)
{
printf("Here I am!\n");
sleep(0.5);
}
exit(0);
}
void* malloc_stack() //used to malloc the stack for the new thread.
{
void *ptr = malloc(STACK_SIZE + 16);
if (!ptr) return NULL;
ptr = (void *)(((unsigned long)ptr & (-1 << 4)) + 0x10); //size align
return ptr;
}
int main()
{
int *bp, *sp;
sp = malloc_stack();
bp = (int*) ((unsigned long)sp + STACK_SIZE);
proc1(&proc2,sp,bp); //the actual code that runs the thread. Written in assembly
assert(0);
}
然后我编写了一个名为 proc1 的简单汇编代码,它接受三个参数,指向函数的指针(用作指令指针)、堆栈指针和基指针,并用这些值替换当前寄存器。我写的代码是:
.globl proc1
proc1:
movq %rdx, %rbp #store the new base pointer
movq %rsi,%rsp #store the new stack pointer
jmp %rdi #jump to the new instruction pointer.
但是当我运行这段代码时,我得到的是一个分段错误。请帮我在这里找到错误。
当我使用以下命令在 GDB 下运行它时,它工作正常:
gcc -g test.c switch.s
gdb a.out
run
但是当它像 ./a.out 一样单独运行时,它就不起作用了!!!! 请帮忙。
提前致谢。
【问题讨论】:
-
对于初学者,您可能不想要“&proc2”... 问:您的编译器/调试器是什么?海合会和 GDB?您是否尝试过在调试器下单步执行您的代码,一路查看关键变量?如果没有,为什么不呢?
-
遇到段错误时,程序员通常会启动调试器以查看段错误发生的确切位置,特别是如果段错误是 100% 可重复的。您也应该这样做,然后可能会更新问题。
-
@paulsm4 在获取函数地址时使用
&是可以的,许多人更喜欢它,因为(可以说)它可以更清楚地说明发生了什么。 -
补充@hyde 的评论:强烈建议在 Linux 机器上使用 coredumps 和 gdb。