2014-01-27 401 views
3

我有一个用GCC编译的Cortex-M3项目。 startup_LPC177x_8x.s代码将已初始化的数据从闪存复制到RAM中,初始化该时钟初始化SystemInit。在调用_main函数之前,代码还会调用函数_libc_init_array什么是__init_array?

__libc_init_array函数调用在__preinit_array定义的所有初始化程序,调用_init功能,并在__init_array定义的所有程序:

void __libc_init_array (void) 
{ 
    size_t count; 
    size_t i; 

    count = __preinit_array_end - __preinit_array_start; 
    for (i = 0; i < count; i++) 
     __preinit_array_start[i](); 

    _init(); 

    count = __init_array_end - __init_array_start; 
    for (i = 0; i < count; i++) 
     __init_array_start[i](); 
} 

随着GDB我能找到的__preinit_array是空的(start == end),并且第二次调用__init_array_start[i]()崩溃。我不知道该数组中包含哪些函数。链接器脚本导致所有.init.array.*部分位于此处。但是,我如何找到相应的.o和源文件?

.init_array : 
{ 
    PROVIDE_HIDDEN (__init_array_start = .); 
    KEEP (*(SORT(.init_array.*))) 
    KEEP (*(.init_array*)) 
    PROVIDE_HIDDEN (__init_array_end = .); 
} >FLASH 
+0

请不要在此引用我,但afaik,gcc将__attribute __((构造函数))调用的函数放入__init_array中。 –

+0

这是一个纯C项目。没有C++构造函数。我相信我从未使用过这个属性。我如何识别这些结构的起源和意义。 – harper

+0

阅读gcc手册;)'__attribute __((*))'构造被gcc用来为函数和变量等启用属性。其中一个属性是“构造函数”,它与C++构造函数无关。在程序启动时和共享库加载时,使用该属性声明的所有函数都以未定义的顺序执行。顺便说一下,请参阅http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html –

回答

1

也许我可以帮助你在这里 -

运行

objdump -D -j .init_array <your-application> 

,你将收到不会忽略的一个列表,像

Disassembly of section .init_array: 

c1008db4 <.init_array>: 
c1008db4: c1000000 .word 0xc1000000 
c1008db8: c1000a68 .word 0xc1000a68 
c1008dbc: c1000b64 .word 0xc1000b64 
c1008dc0: c1000c04 .word 0xc1000c04 
c1008dc4: c1000c68 .word 0xc1000c68 

现在,如果你编译这个你自己,你现在可以跑

addr2line 0xc1000a68 -e <your-application> 

获取有问题的函数的文件名和行号。

这有帮助吗?

+0

objdump 2.22.0.20121207不显示'.word',但尝试反汇编字节。但我可以使用第二列中的原始字节作为地址。我的GCC安装中没有addr2line。但我可以手动使用地图文件并找到一个相应的函数register_fini。这个函数读取一个值检查条件并返回。不幸的是,'__libc_init_array'中的代码在返回之后会跳转到涅ana。 – harper

+0

@harper怪异 - 听起来像是读出init数组的边界,并尝试跳入随机地址(UB)。你能找到'__init_array_end - __init_array_start'的值吗?也许你的工具链出问题了。 –