<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          LWN: 關(guān)閉SIGBUS信號(hào)!

          共 2944字,需瀏覽 6分鐘

           ·

          2021-07-17 06:03

          關(guān)注了就能看到更多這么棒的文章哦~

          Suppressing SIGBUS signals

          By Jonathan Corbet
          June 25, 2021
          DeepL assisted translation
          https://lwn.net/Articles/860419/

          mmap()系統(tǒng)調(diào)用可以給一段虛擬地址區(qū)域創(chuàng)建一個(gè)映射(mapping),這個(gè)函數(shù)有一長(zhǎng)串的參數(shù)來(lái)具體控制這個(gè) mapping 應(yīng)該是怎樣的。Ming Lin 建議新增一個(gè)選項(xiàng),即 MAP_NOSIGBUS。可以用它來(lái)改變進(jìn)程訪問(wèn)未映射(unmapped)地址時(shí)內(nèi)核如何響應(yīng)。這個(gè)選項(xiàng)的作用還是比較容易理解的,但為什么需要用到它,則需要進(jìn)行一些解釋。

          通常情況下,當(dāng)一個(gè)進(jìn)程進(jìn)行內(nèi)存相關(guān)的操作時(shí),它希望能夠從指定的位置讀出或?qū)懭霐?shù)據(jù)。但有時(shí)會(huì)出現(xiàn)異常情況,導(dǎo)致進(jìn)程收到一個(gè) fatal signal(默認(rèn)設(shè)置下)。一個(gè) "segmentation violation"(SIGSEGV)信號(hào)是在試圖以違背保護(hù)方式的情況下訪問(wèn)一個(gè)有效的內(nèi)存地址時(shí)報(bào)出的,比如說(shuō)對(duì)只讀內(nèi)存進(jìn)行的寫入操作。而試圖訪問(wèn)一個(gè)無(wú)效的地址的情況下就會(huì)導(dǎo)致 "bus error"(SIGBUS)。bus error 可能是在多種情況下出現(xiàn)的,比如使用的地址未正確對(duì)齊,或者使用一個(gè)根本沒(méi)有被映射過(guò)的地址。如果某個(gè)進(jìn)程使用 mmap() 創(chuàng)建的 mapping 超出了這個(gè)相應(yīng)文件的末尾,那么如果試著去訪問(wèn)超過(guò)文件末尾的 page 時(shí)就會(huì)觸發(fā) SIGBUS 信號(hào)。

          然而,如果一個(gè)內(nèi)存區(qū)域在映射時(shí)采用了這里提議新增的 MAP_NOSIGBUS flag,那么在訪問(wèn)這塊區(qū)域的無(wú)效地址(invalid address)進(jìn)行訪問(wèn)時(shí)就不會(huì)再產(chǎn)生 SIGBUS 信號(hào)了。相反,這個(gè)導(dǎo)致出錯(cuò)的進(jìn)程將會(huì)得到一個(gè)內(nèi)容全是 0 的新 page。如果這個(gè)映射區(qū)域?qū)?yīng)的是磁盤上的一個(gè)文件,那么新的 page 也不會(huì)被追加寫入到該文件中。簡(jiǎn)單來(lái)說(shuō),新的選項(xiàng)只是消除了 SIGBUS 信號(hào),因此進(jìn)程甚至不知道它曾試圖訪問(wèn)過(guò)一個(gè)無(wú)效的地址。

          OK…but why?

          這種行為看起來(lái)很怪異。人們通常不會(huì)希望某個(gè)被映射的區(qū)域包含了無(wú)效的地址,而且人們通常總是希望能知道某個(gè)程序是否在生成并使用無(wú)效地址的。事實(shí)上,在正常使用情況下,映射的區(qū)域很可能會(huì)包含無(wú)效地址:如果該區(qū)域映射的是一個(gè)文件,并且它包含了超過(guò)磁盤文件末尾的地址。在試圖訪問(wèn)超出文件末尾的 page 時(shí)就將產(chǎn)生一個(gè) SIGBUS 信號(hào);這種情況可以通過(guò)在試圖通過(guò) mapping 來(lái)訪問(wèn)文件之前對(duì)文件進(jìn)行擴(kuò)大操作(extend)來(lái)避免。

          不過(guò) MAP_NOSIGBUS 與這種工作方式是完全沖突的;它在針對(duì)無(wú)效地址所創(chuàng)建的全是 0 的 page 并沒(méi)有跟底層文件關(guān)聯(lián)起來(lái),這樣一來(lái)要想 extend 這個(gè)文件的話就必須要重新生成 mapping 才可以。實(shí)際上,發(fā)明這個(gè)選項(xiàng)是為了解決另一個(gè)問(wèn)題:圖形客戶端(graphical client)可能會(huì)意外地(或有意地)導(dǎo)致 compositor 發(fā)生 crash。

          圖形化的應(yīng)用程序經(jīng)常需要向 compositor 傳遞大量數(shù)據(jù)。一種有效方式就是對(duì)一個(gè)文件生成 mapping 然后將描述符傳遞給 compositor,該文件(可能位于一個(gè)完全在內(nèi)存中的文件系統(tǒng)里)就成為了兩個(gè)進(jìn)程之間的共享內(nèi)存區(qū)域。然而,如果客戶端進(jìn)程后面調(diào)用了 ftruncate()來(lái)縮短文件的大小,那么就會(huì)導(dǎo)致這個(gè) mapping(在 compositor 中)超出了該文件的末尾。如果 compositor 試圖訪問(wèn)超出文件末尾位置的共享內(nèi)存,就會(huì)得到一個(gè) SIGBUS 信號(hào);如果沒(méi)有采取相應(yīng)措施的話,這會(huì)導(dǎo)致 compositor 發(fā)生 crash,這是致力于改善用戶體驗(yàn)的開(kāi)發(fā)者們要盡力避免的事情。SIGBUS 信號(hào)可以在 compositor 中被捕獲并處理掉,但這個(gè)過(guò)程可能很復(fù)雜,也很難做到完全正確。

          正如從事 Wayland compositor 開(kāi)發(fā)工作的 Simon Ser 在四月份時(shí)指出的那樣,還有一種機(jī)制可以用來(lái)在兩個(gè)進(jìn)程之間傳遞數(shù)據(jù):memfd abstravtion。一個(gè) memfd 可以被 "sealed(密封起來(lái))",這意味著創(chuàng)建者無(wú)法像上面說(shuō)的那樣來(lái)縮小這個(gè)區(qū)域(或者說(shuō),實(shí)際上根本不能對(duì)其進(jìn)行改動(dòng));接收者知道這個(gè)區(qū)域不會(huì)意外發(fā)生變化,那么就可以安心地進(jìn)行訪問(wèn)了。但是,正如 Ser 所指出的,沒(méi)有一個(gè) compositor 要求必須 sealed memfd,因?yàn)橛械目蛻舳瞬辉敢饣虿荒苁褂?sealed memfd。因此,compositor 要么小心翼翼地處理好各種 SIGBUS,要么就得冒著不斷觸發(fā) core dump 的風(fēng)險(xiǎn)。

          但是,如果 compositor 能夠以一種不會(huì)在無(wú)效地址上產(chǎn)生 SIGBUS 信號(hào)的方式來(lái)映射一段內(nèi)存的話,整個(gè)問(wèn)題就會(huì)消失了。Ser 建議把 OpenBSD 支持的 __MAP_NOFAULT 標(biāo)志作為一個(gè)可能解決方案。在六月初,Lin 相應(yīng)地提出了 MAP_NOSIGBUS 的實(shí)現(xiàn)代碼,它與 __MAP_NOFAULT 有許多區(qū)別。最初的實(shí)現(xiàn)版本只適用于內(nèi)存中的 tmpfs 文件系統(tǒng),但 Hugh Dickins 提出了反對(duì)意見(jiàn),認(rèn)為它應(yīng)該適用于任何 mapping;第二個(gè)版本 (也是目前修改過(guò)的版本) 就是針對(duì)這一點(diǎn)進(jìn)行了修改,無(wú)論 mapping 背后對(duì)應(yīng)的是什么,都可以使用 MAP_NOSIGBUS。

          Limitations

          當(dāng)前實(shí)現(xiàn)中還有一個(gè)重要限制,它只適用于 MAP_PRIVATE mapping。對(duì)于一個(gè)旨在用于客戶端和 compositor 之間共享的 mapping 的機(jī)制來(lái)說(shuō),這是一個(gè)致命的缺陷。但是,正如 Ser 所解釋的,private mapping 幾乎在所有情況下都能使用,因?yàn)閿?shù)據(jù)傳輸都是單向的,是從客戶端送到 compositor 的,這個(gè) mapping 在合成器那邊可以是只讀屬性的。最明顯的例外情況是屏幕捕捉,如果不能支持 shared mapping 的話,這里就需要進(jìn)行一些特別處理。所以這個(gè)解決方案并不完整,但完成度 90% 的方案已經(jīng)是朝著正確方向邁出的一大步了。

          第二版 patch set 的討論相對(duì)較少,似乎相關(guān)的開(kāi)發(fā)者對(duì)其目前狀況已經(jīng)比較滿意了(盡管有人聽(tīng)到 Kirill Shutemov 對(duì) "one-user features" 這一點(diǎn)有過(guò)抱怨)。盡管沒(méi)有人能夠提供保證,但似乎看起來(lái)很大可能會(huì)在 5.14 版本中將這個(gè)功能合入 mainline。

          全文完
          LWN 文章遵循 CC BY-SA 4.0 許可協(xié)議。

          歡迎分享、轉(zhuǎn)載及基于現(xiàn)有協(xié)議再創(chuàng)作~

          長(zhǎng)按下面二維碼關(guān)注,關(guān)注 LWN 深度文章以及開(kāi)源社區(qū)的各種新近言論~



          瀏覽 37
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  人人摸在线观看 | 四色激情五月婷婷 | www.久久精品 | 亚洲性老太-V888AV | 永久免费一区二区 |