簡體   English   中英

為什么我的sbrk系統調用無法實現?

[英]Why my implementation of sbrk system call does not work?

我嘗試編寫一個非常簡單的操作系統,以更好地理解基本原理。 而且我需要實現用戶空間malloc。 因此,起初我想在我的linux機器上實現並測試它。

首先,我通過以下方式實現了sbrk()函數

void* sbrk( int increment ) {
    return ( void* )syscall(__NR_brk, increment );
}

但是此代碼不起作用。 相反,當我使用os給定的sbrk時,這可以正常工作。

我試圖使用sbrk()的另一種實現

static void *sbrk(signed increment)  
{  
    size_t newbrk;  
    static size_t oldbrk = 0;  
    static size_t curbrk = 0;  

    if (oldbrk == 0)  
        curbrk = oldbrk = brk(0);  

    if (increment == 0)  
        return (void *) curbrk;  

    newbrk = curbrk + increment;  

    if (brk(newbrk) == curbrk)  
        return (void *) -1;  

    oldbrk = curbrk;  
    curbrk = newbrk;  

    return (void *) oldbrk;  
}  

從此函數調用的sbrk

static Header *morecore(unsigned nu)  
{  
    char *cp;  
    Header *up;  

    if (nu < NALLOC)  
        nu = NALLOC;  

    cp = sbrk(nu * sizeof(Header));  
    if (cp == (char *) -1)  
        return NULL;  

    up = (Header *) cp;  
    up->s.size = nu;  // ***Segmentation fault
    free((void *)(up + 1));  

    return freep;  
}  

此代碼也不起作用,在行(***)上出現分段錯誤。 哪里有問題?

謝謝大家 我已經使用sbrk的新實現解決了我的問題。 給定的代碼工作正常。

void* __sbrk__(intptr_t increment)
 {
     void *new, *old = (void *)syscall(__NR_brk, 0);

     new = (void *)syscall(__NR_brk, ((uintptr_t)old) + increment);

     return (((uintptr_t)new) == (((uintptr_t)old) + increment)) ? old :
         (void *)-1;
 }

第一個sbrk可能應具有long increment 而且您忘記了處理錯誤(並設置了errno

第二個sbrk函數不會更改地址空間 (就像sbrk一樣)。 你可以使用mmap改變它(但使用mmap而不是sbrk將不會更新數據片段結尾為內核的觀點sbrk一樣)。 您可以使用cat /proc/1234/maps查詢pid 1234進程的地址空間。 甚至從程序內部讀取(例如,使用fopenfgets/proc/self/maps

順便說一句, sbrk已過時(大多數malloc實現使用mmap ),並且根據定義,每個系統調用 (在syscalls(2)中列出)均由內核執行(對於sbrk內核保持“數據段”限制!)。 因此,您無法避免使用內核,我什至不理解為什么要模擬任何系統調用。 幾乎根據定義, 您無法模擬系統調用,因為它們是從用戶應用程序與內核進行交互的唯一方法。 在用戶應用程序中,每個系統調用都是原子性的基本操作(由一條SYSENTER機器指令完成,並在機器寄存器中包含適當的內容)。

您可以使用strace(1)來了解正在運行的程序執行的實際syscall。

順便說一句, GNU libc是一個免費軟件 您可以查看其源代碼。 musl-libc是更簡單的libc ,其代碼更易讀。

最后,使用gcc -Wall -Wextra -g編譯並使用gdb調試器(如果需要,您甚至可以查詢寄存器)。 也許閱讀x86 / 64-ABI規范Linux Assembly HowTo

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM