Leo Chen

Leo Chen

目前就讀交通大學資工系,並在系資訊中心擔任助教。喜歡研究系統與網路方面的領域,也關注電腦安全的相關技術。以 Rust、C 做主要的程式語言,也會分享相關知識。

Tips

在 Alpine Linux 上用 bindgen 的踩雷紀錄

最近在弄專題時,想說在一個比較單純的環境裡做測試,就挑了 Alpine Linux 來用。結果在編譯時跑 bindgen 吃了不少苦頭。 最一開始是這樣的,bindgen 會回報說無法動態載入 clang 的 shared library,錯誤訊息是 Dynamic loading not supported 。 幸好,bindgen 有提供 static 的 feature 可以用 cargo install --no-default-features --features static,logging,clap,which-rustfmt bindgen但是裝起來之後,一下指令就 Segmentation fault 是怎麼回事?? Debug 了一下就發現,他的 GOT 並沒有 relocate 到正確的地址上,查了很久才發現 rust

Tips

為何在 C 語言中,char ** 無法安全轉換為 const char **?

最近在寫程式時,發現當我把一個 char ** 型態的變數,傳到一個 const char ** 型態的參數時,出現了以下的警告: passing 'char *[257]' to parameter of type 'const char **' discards qualifiers in nested pointer types將 char * 型態轉換為 const char * 是安全的,那為何會這樣呢? 那是因為 char ** 會含有 char * ,因此有可能可以透過其他 char * 去修改 const char * 中的值 以下是一個簡單的範例: const char *bin = "/bin/sh"; char *argv[

Tips

在 Word 裡嵌入程式碼的注意事項

雖然說在 Word 裡塞程式碼並不是什麼好選擇,但是總是會遇到必須這麼做的時候,Ex: 某某教授的作業、要給某某客戶的文件...之類的。然後你就會體會到 Word 是一個 programmer-unfriendly 的玩意 : ( 等寬字體相信大家都知道讓程式碼好看的主要精華就是等寬字,也相信各位一定都有安裝等寬字體,也會知道要套用上去,就會得到: 相信大家都發現了,這空白跟其他字元並不等寬啊啊啊!顯然是 Word 又雞婆的動了手腳,調整了寬度,但這並不是我們想要的結果... 解決這個問題的秘訣在於某個藏起來的設定:「調整半形字及全形字的字距比例」 將它取消勾選就好 這個設定是針對每個檔案去設定的,在調整時要注意是否選到了要調整的檔案 調整完的結果: 舒服~~ 來源:https://answers.microsoft.com/en-us/mac/forum/macoffice2011-macword/monospaced-font-not-aligning-vertically-due-to/8d854439-41c1-4664-91c1-3f3e5de0f111

Tips

在C++的const function存取mutex

在 C++ 中寫 Multi-thread program的時候,為了 Thread-Safety 經常會在裡面塞 std::mutex 。 class ThreadSafe { public: int get() const; void set(int value); private: std::mutex _lock; int data; }; 但這時問題就來了, mutex::lock()/ mutex::unlock() 並不是 const member function,因此在 get() 中 lock mutex 的時候,想必會編譯失敗。 難道我們就得因此犧牲 const member function 的使用嗎? 其實 C++ 有一個鮮為人知的關鍵字

Hareware

ACPI & EC & Linux (一) -- ACPI 與 AML

What is ACPI?古時候的電腦經常會有一個問題,作業系統中許多有關硬體的控制都相當的差。原因主要是當時所用的規範 APM (Advanced Power Management),將硬體的主要控制交給BIOS處理,OS只能做一些簡易的管理。 爾後,Intel & Microsoft & Toshiba 在1997年提出了 ACPI,讓OS可以更加進階的控制硬體。其中,最重要的部份就是 AML (ACPI Machine Language),他是類似於 Java 的 byte code,可以讓  kernel 執行其中的程式,對硬體的 register 進行操作。‌‌ 簡而言之,AML 可以讓 kernel 需要切換裝置或是系統電源狀態時,提供特定的 function 讓 kernel 執行裡面的程式碼。如此一來,以往需要寫進

Administration

用 TPM 晶片登入 SSH

從很久以前就知道我的筆電裡有個 TPM 2.0 的晶片,因為以前從沒接觸過這類的硬體加密裝置,所以就一直想來玩玩看。 不過因為 Linux 這邊的驅動及軟體支援有點問題,更個 BIOS 就爛掉之類的,所以就一直沒去動它… 直到最近 SSH Agent 裡的金鑰有點越來越多了,剛好想起來就來測試一下,發現相關的 Software Stack 已經可以正常存取我的 TPM 晶片啦~所以就來實際應用一下吧。 為什麼用 TPM 進行驗證會比較安全?TPM通常是一塊焊在主機板上的晶片,電腦要使用時會透過  TCG(Trusted Computing Group) 所定義的界面(TCTI)進行通訊,不論是金鑰的產生、儲存、加解密運算等操作都是在晶片內部完成的。 要讀取出私鑰或是強行拆解都是無法的,相較於存儲在硬碟等媒介還要安全。私鑰也不會在運算時被讀取到記憶體中,能降低其他漏洞帶來的影響。 安裝必要套件 (以 Arch Linux為例)$ sudo

Rust

Rust 導引筆記系列 #11 -- 列舉 (enum)

Rust 中也有 enum,用來表示一系列的數值,與其他語言不太一樣的地方在於:它可以儲存額外的資料。 enum State { Init, Success(String), Error { message: String, code: u32, }, }如上所示,每個列舉數值可以帶 Tuple-Like 或 Struct-Like 的資料,這部份有點像 C 的 Enum + Union。這個特質相當有用,在標準函式庫中也大量被使用,其中最重要的就屬 Option<T> 和 Result<T, E> 了。等一下會介紹 Option<T> 的使用,而 Result<

CoffeeBeans

咖啡豆心得:Trunk Coffee 日曬 衣索比亞 耶加雪菲 艾瑞嘉

這篇也是拖欠已久的心得文,這支豆子其實是在咖啡展上買的,雖說老早就喝完了,但我也不知道為啥我到今天才更新上來??? 咖啡豆資訊國家:衣索比亞產區:耶加雪菲 艾瑞嘉海拔:1600~2000m處理法:日曬烘焙度:應該是淺焙沖煮心得與紀錄Trunk Coffee 是一家日本的咖啡店,店長鈴木康夫,這次在咖啡展擔任客座咖啡師,在現場沖煮咖啡。我當時就是喝到了它所沖煮的這支咖啡豆,覺得相當具有特色才買下來的。 與一般的耶加雪菲不同的地方在於:那柑橘類的酸感其實並不會很明顯,取而代之的則是伯爵紅茶、蘋果、香瓜等清新的味道。整體的風味並不會過酸,適合讓不習慣酸感的人嘗試一下不同的咖啡風味。 我所用的沖煮方式與一般的耶加雪菲相同:水溫約92℃、V60濾杯,沒作太多變化。 這次的豆子是我近期以來喝過最高級的了,不過整體下來絕對符合它的價錢,有機會可以買最小包的1/4磅嘗鮮。 (因為圖片拍太醜就不放了

Rust

Rust 導引筆記系列 #10 -- 結構 (struct)

在程式語言中,要定義自訂的類型一般都會使用 struct 或 class 等之類的關鍵字來定義。 定義在 Rust 中是用 struct 這個關鍵字進行定義。基本上寫起來會長這樣: struct Time { hour: u32, minute: u32, second: u32, }每一個欄位都是以 名稱: 類型 的方式定義,這個模式跟變數定義 (通常類型會省略) 與函數參數的定義方式是一樣的。 建構當定義好一個結構之後,就可以用以下方式建立它: struct Time { hour: u32, minute: u32, second: u32, } fn main() { let t = Time { hour: 8, minute: 12, second: 56, }; }欄位存取使用 obj.

CoffeeBeans

咖啡豆心得:步昂咖啡 水洗 巴拿馬 波奎特 哈拉蜜優

這次的豆子是在挑選校運會擺攤的手沖品項時,想說沒試過這種主打堅果與焦糖的中南美洲豆,所以就買了。沒想到最後成了校運會的正式品項😁 咖啡豆資訊國家:巴拿馬產區:波奎特 哈拉蜜優品種:卡杜拉(Caturra)/卡杜艾(Catuai)海拔:1400m處理法:水洗烘焙度:中焙風味描述:焦糖、堅果我借個咖啡社粉專倒數圖來用…沖煮心得與紀錄基本上用一般的手沖方式就可以了,水溫使用88℃上下。其風味就如同包裝上所描述的一樣,充滿著堅果與些微焦糖的感覺。且堅果的餘韻會持續在口腔中流轉,是一隻相當有特色的咖啡。它的酸感理所當然地少很多,我認為甚至可以用一些手法將其壓掉,適合給不習慣咖啡酸感的人飲用。由於處理法採用水洗再加上本身特性的關係,風味的表現相當乾淨,但卻又略顯單調。就整體風味表現而言,前段酸值不高、中段以濃厚的烤堅果香氣及甜感為主調、最後以微微的焦糖風味做結,喝完後堅果的餘韻會迴繞在口腔中,是十分特別的豆子。 在校運會擺攤時用的沖煮手法是參考花瓣濾杯甜感沖煮法去作調整的,詳細介紹可以參考一下影片。 這次的心得比較少,大概也是因為它比較好懂,風味相當突出、簡單,所以心得文也變簡單了😋(我還真不知道要怎麼寫的更多了…)

Rust

Rust 導引筆記系列 #08 -- if 條件

if 判斷式雖然說在前面應該有見過不少次了,但還是要正式介紹一下。 Rust 的 if 判斷式大致上長這樣: if a > 20 { do_something(); } else { do_otherthing(); }整體上,看起來和目前主流的大多數語言都是一樣的語法。不過還是有許多地方是不同的,最明顯之處莫過於 if 之後的條件判斷是不需要加括號的,而且編譯器也會建議你拿掉它。 至於另一個不同之處也是我喜歡 Rust 的原因之一。 陳述式與表達式 (Statement & Expression)一般在程式語言中,語句會分為兩類:陳述式與表達式,兩者的概念大概是這樣: 陳述式:代表去執行一件工作,不會具有回傳值。在 C/C++/Java 等語言中,分號就是一個陳述式的結尾。表達式:程式中的一部分往往可以計算出一個值,像是 a < b 、 100

Rust

Rust 導引筆記系列 #07 -- 借用與參照

物件借用 (Borrowing)在上次的最後有提到,若是要暫時取得某個不具 Copy 特徵的使用權,就要把所有權傳給該函式,再傳回來。 這顯然不是一個好方法,所以這次就要來介紹「借用」這個機制。 與 C 語言中的取址運算子相當類似,在一個變數的前方加上 & 符號,就可以借用一個變數的數值。在 Rust 中,「借用」會讓我們拿到一個參照,指向被借用的數值。 利用這個機制,我們可以將上一篇最後的範例改為 fn print_string(s: &String) { println!("The string is: {}", s); } fn main() { let str = String::from("My name is Leo, nice to

Rust

Rust 導引筆記系列 #06 -- 物件所有權 (Ownership)

從本篇開始,就要進入核心部份了。所有權的傳遞與借用是 Rust 能在記憶體安全性保證之下卻又不需要垃圾回收器 (Garbage Collector, GC) 的關鍵,也是讓效能足以與 C++ 批敵的特性。 溫馨提醒:本篇具有一些重要觀念,請帶著清楚的腦袋閱讀~~ 值與變數與所有權 (Value & Variable & Ownership)首先,我們需要建立一個觀念:變數和它所帶有的值是不同的兩種東西 變數就如同是一個容器,可以在裡面裝入數值(內容物)。當在讀取變數時,實際上是在讀取內容物的部份,因此,變數必須要有數值才可以讀取它。在一般使用上,也是如此。 在 Rust 中,每個數值(內容物)都對應到一個變數(容器),這個變數稱作「擁有者」(Owner);也就是每個數值只能被裝在一個變數裡。 當變數脫離它的作用域時,裡面的數值就會自動被捨棄 (dropped),這個變數也不再能被使用。 fn main(

Rust

Rust 導引筆記系列 #05 -- 基本資料型態 II

接續上次沒寫完的部份...補充一下陣列或複合類的資料結構吧 陣列Type Annotation: [T; n] Rust 的陣列必須是固定長度的物件,當長度小於等於32時,就會幫你實作一些功能(比較、預設值…等) fn main() { let prices = [25, 35, 40, 50, 55]; // Initialize 8 elements as 100 let array = [100; 8]; // 64 Bytes Empty Binary Data let bin = [0u8; 64]; // Access index 1 println!("Price of the second item: {}", prices[