2015-01-09 50 views
2

是否有允許運行時結構內省的C語言工具?在運行時C結構內省

上下文是這樣的: 我有一個響應外部事件的守護進程,並且對於每個事件我們都帶着一個執行上下文結構(「context」)。上下文很大很混亂,並且包含對各種狀態的引用。

事件處理完成後,我希望能夠通過過濾器運行上下文,並且如果它符合某些條件集,請刪除日誌消息以幫助進行調試。但是,因爲我希望將其用於現場調試,所以我不知道在運行時間之前過濾哪些條件是有用的。

我的理想解決方案將允許用戶從本質上寫出一個C風格的布爾表達式並讓程序使用它。喜歡的東西:已被到處濫用

activate_filter context.response_time > 4.2 && context.event.event_type == foo_event 

想法到目前爲止,包括:

  • 提供了一組有限的,我們知道如何訪問字段。
  • 將所有相關的結構包裝在運行時生成自檢工具的某種宏中。
  • 編寫一個知道哪裏(版本化)頭文件存在的python腳本,生成C代碼並將其編譯爲一個dll,然後該守護程序將加載並用作過濾器。顯然這種方法有一些額外的安全考慮。

在我開始一些瘋狂的設計鵝追逐之前,有沒有人知道這種事情在野外的例子?我穹頂了一些谷歌搜索,但沒有提出太多。

+3

沒有內置的內省。你可以設計出近似自省的系統(靜態定義的結構來描述其他結構),'sizeof'運算符和''中的'offsetof'宏可以提供幫助。類型編碼是一個完全獨立的bag'o'worms。 – 2015-01-09 21:52:07

+1

你可能會發現[有沒有在循環中打印'struct'成員的方法,而不用C中每個成員的名字?](http://stackoverflow.com/questions/27496245/is-there-a-way-to-print -struct-members-in-a-loop-without-naming-each-member-in -c/27497861#27497861)對你有幫助,否則你可能不會。 – 2015-01-09 21:55:55

回答

0

您可能從錯誤的一面接近了這個問題。

日誌記錄通常用於幫助調試。該程序將各種事件寫入日誌文件。提取有趣的條目過濾應用於日誌文件。

有時一個程序產生的事件太多;日誌庫通常通過提供冗長控制來解決這個問題。基本上,日誌功能需要一個額外的參數來告訴當前消息的詳細程度。如果該值高於全局配置的閾值,則該消息被丟棄。一些圖書館甚至允許以每個模塊爲基礎控制詳細程度(例如:谷歌日誌)。

另一種可能的方法是利用調試器的強大功能,因爲調試器可以訪問各種元信息。可以爲任意條件創建一個條件斷點測試變量。一旦程序停止,可以從示波器提取任何信息。這可以使用調試器提供的腳本工具來自動執行(gdb有很好的功能)。

最後,有一些工具可以生成粘合代碼,以使用腳本語言的C庫。 SWIG就是一個例子。它分析頭文件並生成代碼,允許腳本語言調用函數,訪問結構字段等。

您的過濾器表達式將成爲Lua(同時支持其他腳本語言)中的程序。你調用這個程序傳入指向執行上下文結構(「上下文」)的指針。由於SWIG生成的訪問器Lua程序可以檢查結構中的任何字段。

+0

好得多,學習一個工具而不是學習lex和yacc和xml解析等。 – user3629249 2015-01-09 23:28:00

+1

感謝您的迴應!你說得對,這是對記錄的非典型使用。不幸的是,這個程序每秒處理數十萬個事件,並且記錄所有這些事件都會對性能產生巨大影響。我已經使用基本過濾器進行了一些實驗,並且它們似乎沒有相同的減速過程。我懷疑在調試器中運行會有類似的性能影響,而且我們希望在客戶站點的實時服務器上使用此工具。但我一定會檢查出SWIG。 – Dan 2015-01-12 18:54:14

1

我也建議從另一個角度來解決這個問題。在你的問題的關鍵詞是:

的背景是大而凌亂

而這正是問題的。一旦你清理了這些,你可能會想出一個乾淨的日誌記錄工具。

考慮以一些簡單易用的格式重新定義您的上下文struct中的所有字段,如XML。一個簡單的XML模式,它列出了結構的所有成員,它們的類型,以及其他一些元數據,甚至包含記錄該字段的註釋。

然後,將一個快速而髒的樣式表放在一起,該樣式表讀取XML文件並生成一個可編譯的C結構體,您的代碼實際使用該結構體。然後,生成一個不同的樣式表,用於生成robo生成的代碼,枚舉結構中的每個字段,並生成將每個字段轉換爲字符串的代碼。

從此,用某種用戶提供的過濾字符串栓上某種日誌工具變得更容易。你必須想出一些解析任意過濾字符串的方法。瞭解lexyacc會派上用場。

這種性質的事情已經做過。

XCB library是X11協議的C客戶端庫。該協議定義了各種各樣的二進制消息,這些消息本質上是簡單的,客戶端和服務器通過套接字相互拋擲。實現libxcb的方式是,所有X11消息及其內部的所有數據類型都在XML定義中描述,樣式表robo-生成C結構定義以及解析它們的代碼,並提供一個相當乾淨的C API解析並生成X11消息。