2012-12-18 124 views
4

在Linux中。每對dlsym(3)Linux手冊頁,爲什麼dlsym()返回的符號值爲空?

*Since the value of the symbol could actually be NULL 
    (so that a NULL return from dlsym() need not indicate an error),* 

這是爲什麼,當可在符號(函數,特別是)是實際NULL?我正在審查代碼,並找到一個使用dlerror首先清理,dlsym next和dlerror檢查錯誤的作品。但在調用它之前,它不會檢查由此產生的函數爲空:

  • dlerror();
  • a_func_name = ... dlsym(...);
  • if(dlerror())goto end;
  • a_func_name(...); //從不檢查a_func_name == NULL;

我只是一個評論者,所以沒有選擇只是添加支票。也許作者知道NULL永遠不會被返回。我的工作是挑戰,但不知道什麼可以使這個返回一個有效的NULL,這樣我就可以檢查在這個代碼的上下文中是否可以滿足這樣的條件。沒有找到適合Google閱讀的內容,除非您想明確說明哪個更好,否則指向好的文檔就足夠了。

+1

您可以在彙編程序中或使用GCC特定技巧定義給定的符號位於地址0,並且您可以「符合」該符號。 –

+0

明白了。謝謝。 – bokusama

回答

1

那麼,如果它沒有錯誤地返回,那麼指針是有效的,並且NULL與來自共享對象的任何隨機指針大約是非法的。像錯誤的功能,數據或其他。

+3

如果返回值是共享變量(或函數)的*值*,這將有意義。但它應該是地址,是不是(或者是否依賴於標誌)?那麼,大概它實際上是從一張地址表中讀取一個值,並且該二進制文件可以被編輯爲在該表中具有零(或者如你所說的任何無效指針)。 –

+0

嗯,我不確定,但不能輸出符號有絕對地址? –

+0

確實。謝謝。 – bokusama

-1

dlerror()返回最後一個錯誤,而不是最後一次調用的狀態。因此,如果沒有其他代碼,您顯示的代碼可能會從dlsym()得到有效的結果,並且自欺欺人地認爲存在錯誤(因爲隊列中還有一個錯誤)。 dlerror背後的目的是提供人類可讀的錯誤消息。如果您不打印結果,則說明您使用的是錯誤的。

+3

這就是在* dlsym之前立即調用dlerror()的目的 - 清除最近的錯誤變量。沒有隊列(如果可以相信手冊頁)。 –

+0

啊,錯過了。是的,所以這是毫無意義但是正確的。 'dlsym'被記錄爲錯誤時返回NULL,但是'dlerror'的非NULL結果是等價的(禁止線程安全錯誤之類的事情 - 如果另一個線程做同樣的廢話,顯然這裏有一場競賽)。這仍然是對API的濫用。 –

+0

當然,每個線程都有自己的錯誤變量副本。無論如何,這是調用API的正確方式,而不是濫用。比較:'errno = 0; int a = itoa(s);如果(errno)...'因爲'如果(a)'不能區分s =「0」;'from's =「Garbage」;'。 –