【问题标题】:Symbols in dylib, Works with gcc-4.0 not in gcc-4.2 (OSX-default)dylib 中的符号,适用于 gcc-4.0 而非 gcc-4.2(OSX 默认)
【发布时间】:2011-04-16 06:22:37
【问题描述】:

我有一个我用它构建的动态库

OBJECTS=keys.o etc2.o foo.o
$(CC) -DSYS_MACOSX  -g -fPIC -flat_namespace -L. -lpthread  -Wl,-flat_namespace -dynamiclib  -shared -o libmylib.dylib $(OBJECTS)

我的测试程序链接到这个库

$(CC) -DSYS_MACOSX  -g -fPIC testmain.c -o testmain -I. -flat_namespace -L. -lpthread  -lmylib 

当 CC=gcc-4.2 在 gdb 中出现以下错误时,当我尝试访问 libmylib.dylib 中的 const 符号时:

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000112dd0
0x0000000100004ec7 in extractKeyFromList (keyList=0x112dd0, key=0x1002001e0 "Adresse1.aName1") at keys.c:148

该程序适用于:

  • 雪豹上的 gcc-4.0
  • Debian i386 上的 gcc-4.3.2
  • gcc-4.1.2 用于 arm-angstrom-linux-gnueabi

更新:这是 Lib 中的一些调试输出 main=main loadKeyList=function

GCC 4.0:

main:            sizeof KeyList =  149480
loadKeyList:     sizeof KeyList =  149480
loadKeyList:     list at 0xfe88c
loadKeyList:     sizeof list =  149480
loadKeyList:     list->count 3086
main:            sizeof handle->keyList = 149480
main:            handle->keyList at 0xfe88c
main:            handle->keyList->count 3086

GCC4.2

(gdb) run
Starting program: keyextractor -k Adresse1.aName1
Reading symbols for shared libraries ++. done
main:            sizeof KeyList =  166088
loadKeyList:     sizeof KeyList =  166088
loadKeyList:     list at 0x112dd0
loadKeyList:     sizeof list =  166088
loadKeyList:     list->count 3086
main:            sizeof handle->keyList = 166088
main:            handle->keyList at 0x112dd0

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000112dd0
0x0000000100001940 in main (argc=3, argv=0x7fff5fbfefb8) at keyextractor.c:110
110     printf("main:            handle->keyList->count %i\n", handle->keyList->count);
(gdb) 

结构看起来像这样:

typedef struct _KeyList {
    int count;
    Key keys[4152];
} KeyList;

更新 2:这适用于 main 的 gcc-4.2

printf("KEYMAP.keyList[5] at 0x%x count = %i\n", &KEYMAP.keyList[5], KEYMAP.keyList[5].count);
Output: KEYMAP.keyList[5] at 0x112dd0 count = 3086

和指针句柄一样的地址->keyList!

KEYMAP 看起来像:

typedef struct _KeyMapList {
    int count;
    KeyList keyList[];
} KeyMapList;

const KeyMapList KEYMAP = {
  .count = 6,
  .keyList = {
   { ... }, { .... },
   { ... }, { .... },
   { ... }, { .count=3086, keys.... }
   }
};

那么 gcc-4.2 有什么问题呢?

谢谢

【问题讨论】:

  • 您是否尝试过调试问题?例如。在 gdb 下运行程序,在它崩溃时进行回溯,然后从那里开始工作?
  • 是的......当它试图访问一个结构的成员时它崩溃了。 148 int last = keyList->count;上面的 gdb-Error
  • 我认为我们需要查看一些代码来帮助解决这个问题——可能你得到了未定义的行为,它可以在不同的编译器上做不同的事情
  • 我已经更新了示例。基本上,我从 dylib 中的函数获得了指向 Struct KeyList 的指针。 list 和 handle->keyList 具有相同的地址,但访问 ->count-Member 只能从 gcc4.2 中的 dylib 函数内部进行。 gcc4.0同时允许

标签: c macos gcc exc-bad-access dylib


【解决方案1】:

好的.. gcc 似乎没有问题。

这是 x86_64 架构的问题。 使用“-arch i386”构建解决了 gcc4.2 的问题。

我仍然不知道,为什么它不适用于 x86_64。 binary 和 dylib 都是 x86_64:

libmylib.dylib: Mach-O 64-bit dynamically linked shared library x86_64
keyextractor:   Mach-O 64-bit executable x86_64

【讨论】:

    【解决方案2】:

    我的程序在 Linux-x86_64 上也失败了

    但真正的答案是:你应该听 gcc 警告并使用 -Wall 进行编译

     keyextractor.c:114: warning: cast to pointer from integer of different size
    

    这个警告在我从 Lib 中调用一个函数的行中,没有 #include-ing 相应的 Header-File。 如果没有函数声明,它就可以工作:

    • i386 架构为共享库和静态
    • x86_64 架构仅静态

    因此,在包含正确的头文件后,一切正常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-09
      • 1970-01-01
      • 2013-12-29
      • 1970-01-01
      • 2022-12-08
      • 1970-01-01
      • 2011-09-10
      • 1970-01-01
      相关资源
      最近更新 更多