簡體   English   中英

靜態函數和變量在共享庫中導出

[英]Static function and variable get exported in shared library

到目前為止,我假設C中具有靜態鏈接(即靜態函數和靜態變量)的對象不會與其他編譯單元(即.c文件)中的其他對象(靜態或外部鏈接)發生沖突,所以我使用了“簡短的“內部幫助函數的名稱,而不是使用庫名稱前綴所有內容。 最近,由於名稱與另一個共享庫中的導出函數發生沖突,我的庫的用戶遇到了崩潰。 經過調查,我發現我的幾個靜態函數是共享庫的符號表的一部分。 由於它發生在幾個GCC主要版本中,我認為我缺少一些東西(這樣一個主要的bug會被注意到並修復)。

我設法將其歸結為以下最小示例:

#include <stdbool.h>
#include <stdlib.h>

bool ext_func_a(void *param_a, char const *param_b, void *param_c);
bool ext_func_b(void *param_a);

static bool bool_a, bool_b;

static void parse_bool_var(char *doc, char const *var_name, bool *var)
{
    char *var_obj = NULL;

    if (!ext_func_a(doc, var_name, &var_obj)) {
       return;
    }
    *var = ext_func_b(var_obj);
}

static void parse_config(void)
{
    char *root_obj = getenv("FOO");
    parse_bool_var(root_obj, "bool_a", &bool_a);
    parse_bool_var(root_obj, "bool_b", &bool_b);
}

void libexample_init(void)
{
    parse_config();
}

靜態變量bool_a和靜態函數parse_bool_var都可以在目標文件和共享庫的符號表中看到:

$ gcc -Wall -Wextra -std=c11 -O2 -fPIC -c -o example.o example.c
$ objdump -t example.o|egrep 'parse_bool|bool_a'
0000000000000000 l     O .bss   0000000000000001 bool_a
0000000000000000 l     F .text  0000000000000050 parse_bool_var
$ gcc -shared -Wl,-soname,libexample.so.1 -o libexample.so.1.1 x.o -fPIC 
$ nm libexample.so.1.1 |egrep 'parse_bool|bool_a'
0000000000200b79 b bool_a
0000000000000770 t parse_bool_var

我已經潛入C11, Ulrich Drepper的“如何編寫共享庫”以及其他幾個解釋符號可見性的來源,但我仍然不知所措。 為什么bool_aparse_bool_var在動態符號表中結束,即使它們被聲明為static

nm輸出的第二列中的小寫字母表示它們是本地的(如果它們是大寫的,那么它將是一個不同的故事)。 這些符號不會與同名的其他符號和AFAIK沖突,基本上只用於調試目的。 局部符號不會進入動態符號表(可以使用nm -D打印,但只能在共享庫中打印)並且它們是strip pable以及非動態的導出符號( nm輸出的第二列中的大寫字母) 。

(正如您將從Drepper的如何編寫共享庫中學到的,您可以使用-fvisibility=(default|hidden) (不應使用受保護)和可見性屬性來控制可見性。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM