簡體   English   中英

Fork系統調用失敗后,rax中的返回值是多少?

[英]What is the return value in rax after a failed Fork syscall?

我知道如果有錯誤,在C中調用fork()會返回-1,但是我想知道在匯編中調用sys_fork時錯誤返回值是多少。

我通常可以假設它也返回-1,但是我已經處理過sys_brk,而匯編中的原始syscall返回的內容與C Brk()包裝器有所不同。

有誰知道匯編中的fork錯誤返回值是什么?

(我正在Linux上進行64位NASM組裝)

首先注意,在C庫包裝fork(2)調用sys_clone和不sys_fork

C庫/內核差異

從2.3.3版開始,而不是調用內核的fork()系統
調用,作為NPTL的一部分提供的glibc fork()包裝器
線程實現調用帶有提供以下內容的標志的clone(2):
與傳統系統調用效果相同。


Linux手冊第2節簡介介紹了如何在一般情況下解釋系統調用的返回值:

返回值

發生錯誤時,大多數系統調用都會返回負錯誤號 (即
errno(3)中描述的常數之一的取反值。 C
庫包裝程序向調用方隱藏了此詳細信息:系統調用時
返回負值,包裝器將絕對值復制到
errno變量,並返回-1作為該變量的返回值
包裝。

因此,對於大多數系統調用,EAX / RAX -ESOMETHING在錯誤時保留-ESOMETHING ,或者在成功時保留非負結果。 libc包裝器對此進行解碼,以實現第2節手冊中描述的errno設置和返回-1行為,這些手冊主要記錄了包裝器; 有時會在Linux手冊頁的“注釋”部分中找到“ C庫/內核差異”的詳細信息。

重要的是要注意,正如第一段所述,這適用於大多數但並非所有系統調用。 sys_fork在這方面並不特殊。 一對夫婦有趣的特殊情況是getpriority在開頭提到的errno(3) 更下方mmap (有效的指針可以將其高位設置為1,因此,將錯誤與成功區分開來還需要其他技巧, 例如檢查低位,因為成功的mmap總是返回頁面對齊的地址 。)這些ABI詳細信息未在手冊頁中記錄。


為了找出sys_fork調用是否成功,測試一個負值就足夠了:

test eax, eax
jl _error_handler              ;See Peter Cordes's comments below

我包括了有關C庫包裝程序的部分,例如fork(2)因為它提供了一種實用的方法來找出錯誤號。
否定的errno值是系統調用可以返回的可能的錯誤值。

EAGAIN
ENOMEM
ENOSYS
ERESTARTNOINTR

通常,C庫包裝器可以在將返回值寫入errno之前對其進行添加,刪除或轉碼,因此這是失敗的。

確定可能的返回值的最終方法是查看源。
例如,由sys_fork調用的do_fork除了上面列出的值之外,還可以返回EINVALEPERM
其他值也是可能的,我還沒有深入研究所有嵌套函數調用。

sys_clone還調用do_fork因此我假設clone(2)可以返回fork(2)可以的所有錯誤號。


在調查上述sys_getpriority的情況下,出現了一條評論

/*
 * Ugh. To avoid negative return values, "getpriority()" will
 * not return the normal nice-value, but a negated value that
 * has been offset by 20 (ie it returns 40..1 instead of -20..19)
 * to stay compatible.
 */

因此,似乎Linux系統調用總是在出錯時返回負值,而C庫包裝程序則試圖將這些值歸一化為errno ,從而引入了額外的復雜性。

mmap情況可以看出,設置符號位並不總是意味着它是一個錯誤值。 根據此答案 (值得彼得·科德斯評論),范圍[-4095,-1]中的值始終表示錯誤,而其他負值則不應。

暫無
暫無

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

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