linux啓動一個二進制程序
linux程序在用戶態啓動運行時,會內核先自己搞一些小動作:
fork-》複製頁表-》複製VMA(PTE)-》copyprocess()(好像是這個)-》copythread()(好像是這個)-》僞裝好進程執行時的現場、
初始化調度相關的東西-》加入可執行隊列等待調度-》其餘的啥忘了
若是在shell執行的程序,調度到所執行程序時,可能shell會有exec來加載程序代碼,
但是也不是一次性全加載,記錄下硬盤可執行文件每部分的地址,和載入內存後的地址(虛址),
這就算加載完了。當調度到程序執行缺代碼時,會缺中然後去硬盤讀代碼。
堆棧細節
linux程序的棧、堆
本質上,棧應該算是數據結構,或者應該算是一種內存使用方式,並不是說有一個東西叫棧。
程序執行的規則裏,局部變量、函數調用,按照FILO的方式往一段內存裏寫。就有了棧,於是爲什麼會爆棧。
另:內核知不知道棧?
知道的,內核多精,一看這貨吃完不拉直往外吐;點點頭,這貨是棧,限制一下大小,吃多了不吐就炸了它。
堆
malloc等的就在堆,就是個垃圾堆。垃圾吃多了,一不小心就會頂破棧,這也是一種程序異常。
解釋器細節
linux程序的解釋器
不要誤會,這裏說的不是shell類的解釋語言。就是二進制程序,linux的二進制程序是需要解釋器的。
在所有的linux中(包括完成閹割的小android)
/lib下(安卓/system/lib下),有一個ld-*.so,搜索了NNNN多東西,沒找到他是做什麼的
最終再oracle linux的相關文檔裏查到ld-*.so,是一個運行時解釋器,調用了.so的運行的程序是要依靠ld-*.so找到動態庫運行的。
注意,對ld-*.so的調用應該是在sh fork完進程,執行exevc()時調用。
這也是純種普通的編譯成aarch64指令的linux程序爲什麼不能在安卓直接執行;
因爲猥瑣的谷歌,在AndroidO上用了不同的解釋器叫ld-android.so
於是,linux應用來安卓的時候請自備解釋器(解釋器文件名是相關的)。
如生孩子般複雜的製作-linux二進制程序的生產過程
預處理->編譯->彙編->鏈接
預處理
這一過程將所有宏打開,此時C還是C,但是宏卻不是宏了。。。
這裏需要指出,預處理階段有豐富的編譯選項
-Werror 可以輕易讓你的警告變成錯誤(想編譯?見鬼去吧!)
-Wtraditional 代碼遵循ISO C會產生警告(打不斷你煩死你)
-Wall 開啓所有警告(強迫症必選,注入char 和unsigned char撲面而來)
。。。總之,正事不少,花活兒也挺多。但大致與平臺無關。
編譯
這一步是非常複雜的操作,由gcc的神奇大隊長gcc-core來做,gcc-core會進行詞法分析(感謝有詞法分析,不然鬼才知道把define都落實了的鬼畫符會是什麼東西。不過就算有詞法分析,也就語法分析有可能—————————————
。。。。這篇blog有點古老,不太全了,還有一截不知道哪兒去了,等找到了再續上