diff -u: 核心開發裡的新鮮事兒

Zack Brown發表於2022-11-28

偶爾總會有人指出Linux中的POSIX違規(violation),通常的回答是“修復違規問題”,但有時李納斯·託瓦茲認為POSIX特性是不完整的,至少他們維護Linux特性的情形下是這樣的。因此,他們或許應該構建一層POSIX相容層,即便這個分層會相對較慢和低效。

這一次,邁克爾·凱利斯克(Michael Kerrisk)報告了一個影響檔案操作的POSIX違規。顯然,在多執行緒操作期間讀寫檔案會導致競爭出現,重寫其它操作的改變。

關於這是否是POSIX的一個違規存在一些討論,但到最後又有誰關心呢?資料重寫(clobbering)是很糟糕的事情。在邁克爾提交部分程式碼去重現這個問題後,討論的問題集中到該做什麼去修復它。但邁克爾的觀點是:“Linux從早期開始就與UNIX不一致。(如在1992年版的史蒂夫的APUE的191頁討論到fork()操作後在父程式與子程式之間檔案偏移量的共享問題。儘管史蒂夫沒有顯式地講清楚一致性的保證,但缺乏這個保證的推論這裡的討論可能有些沒意義。)”

艾爾·維洛(Al Viro)和李納斯一起設法解決這個修復。李納斯嘗試引入一個簡單的互斥量去鎖住檔案,以便寫操作無法互相重寫。艾爾提出了自己的改進以改善李納斯的補丁。

李納斯一度解釋過這個故障自身的歷史。顯然,從前這個用來告訴系統去哪裡寫檔案的檔案指標已經被鎖在一個訊號量中,所以只有一個程式可以在某一時刻對這個檔案做任何操作。但是,他們從中拿走了這個訊號量,以便在任何時候可以適應裝置檔案和其它非常規檔案,因為當使用者被禁止寫入其中時它們就會陷入競爭狀態。

這就是錯誤的由來。那個時候,它悄悄地透過了檢查,未被發現。因為實際上對常規檔案的讀寫仍然由核心自動處理。只有檔案指標自身可以避免同步。而且,因為高速執行緒化的檔案操作是一個非常罕見的需求,所以對任何人來說都需要很長時間才能遇到這個問題並報告它。

一個有趣的小細節是當李納斯和艾爾在尋找一個修復方案時,艾爾一度抱怨李納斯採用的方法並不能支援一些確定的架構,包括ARMPowerPC。李納斯的回應是“我懷疑關心這個是否有意義。[...]如果使用ARM/PPC架構的人停止抱怨,他們可以往gcc中加入struct-return的支援。”

看到這些問題突然產生並得到處理通常是很有趣的。在某些情況下,這個修復的部分工作必須在核心中進行,部分在GCC中,部分在其它地方。在這個特例裡,艾爾認為整個事情都應該在核心裡處理,他在靈感的激發下往補丁中寫入了自己的版本,李納斯也接受了。

安迪·克倫(Andi Kleen)則想為perf增加底層CPU事件支援。問題在於這可能會導致大量的底層事件,而且會因CPU的變化而改變。即使為了所有型別的CPU把可能的時間都儲存在記憶體裡,也可能會顯著地增加核心的執行大小。因此,把這個資訊硬編碼進核心的方法是有問題的。

他也指出OProfile工具依賴於這些時間的公開可用列表,儘管他表示OProfile開發者並非總維持他們的列表與最新的可用版本一致。

為了解決這些問題,安迪提交了一個補丁,允許perf識別在給定的系統上為特定的CPU需要那種事件列表,並自動從起始位置下載這個列表的最新版本。然後perf可以解釋這個列表並分析其中的事件,不會使核心負載過重。

有各種各樣對安迪程式碼的反饋,其中大部分涉及到應該在哪個目錄下儲存事件列表和檔案如何命名。這份程式碼本身的特性似乎得到了很好的回應。一處細節證明了安迪的程式碼比其他人的更有爭議,就是將列表下載到使用者家目錄下的一個子目錄。安迪表示如果不這樣做的話,使用者可能會以系統管理員的身份去下載事件列表,這會是危害安全的操作。

薩沙·萊文(Sasha Levin)最近釋出了一個指令碼來從堆疊轉儲中把十六進位制的偏移量翻譯成有意義的指向核心原始碼檔案的行號。因此諸如“ffffffff811f0ec8”形式的十六進位制表示可以被翻譯成“fs/proc/generic.c:445”。

然而,結果表明李納斯·託瓦茲正打算從堆疊轉儲中移除十六進位制偏移量,具體原因是他們難以理解。所以薩沙的程式碼看起來過時了。[譯者注:程式媛,傷不起!:< ]

他們在這個問題上糾結了一番。起初,薩沙打算依賴儲存在System.map檔案裡的資料區補償,但李納斯指出包括他在內的有些人並不會保留System.map檔案。李納斯推薦使用/usr/bin/nm從編譯好的核心檔案中提取符號表。

所以,似乎薩沙的指令碼可能確實為除錯堆疊轉儲提供了有意義的檔案和行號,假設堆疊轉儲提供足夠的資訊去完成計算。


via: http://www.linuxjournal.com/content/diff-u-whats-new-kernel-development-0

原文作者:Zack Brown

譯者:KayGuoWhu 校對:wxy

本文由 LCTT 原創翻譯,Linux中國 榮譽推出

相關文章