requimrar wrote:max wrote:
EDIT 1: Its an issue with my global constructor calling... *researching on*
The wiki has some code on global constructors for C++, shouldn't be that hard to find.
Yes, but I also want to understand what I'm coding there.
I just wrote a method that calls all the ctors, and this is the outcome:
In QEMU, in total 4 global constructors get called. Ive added outputs for the address of each constructor, and "called" if it was called. QEMUs output is:
Code: Select all
0x001013AD called 0x00101E4E called 0x00102B06 called 0x0010427B called
So this is right, as I am linking my ctors to the .rodata block after my .text section.
Running the same image in Bochs, it hangs at calling the first one:
Using objdump to find out what symbol is behind that address told me that there is this:
Code: Select all
001013ad l F .text 0000001c _GLOBAL__sub_I_settings
What is this? oO
EDIT: SOLUTION FOUND
Okay, I created a .text-dump with objdump using:
Code: Select all
objdump -t --section .text --disassemble --demangle kernel >kernel.textdump
This revealed the following:
1. The "_GLOBAL__sub_I_settings" is a generated function, calling "__static_initialization_and_destruction_0"
Code: Select all
001013ad <_GLOBAL__sub_I_settings>:
1013ad: 55 push %ebp
1013ae: 89 e5 mov %esp,%ebp
1013b0: 83 ec 18 sub $0x18,%esp
1013b3: c7 44 24 04 ff ff 00 movl $0xffff,0x4(%esp)
1013ba: 00
1013bb: c7 04 24 01 00 00 00 movl $0x1,(%esp)
1013c2: e8 7f ff ff ff call 101346 <__static_initialization_and_destruction_0(int, int)>
1013c7: c9 leave
1013c8: c3 ret
1013c9: 90 nop
2. The "__static_initialization_and_destruction_0" pushes some stuff, and then calls the constructors for one of my HashMaps:
Code: Select all
00101346 <__static_initialization_and_destruction_0(int, int)>:
101346: 55 push %ebp
101347: 89 e5 mov %esp,%ebp
101349: 83 ec 18 sub $0x18,%esp
10134c: 83 7d 08 01 cmpl $0x1,0x8(%ebp)
101350: 75 59 jne 1013ab <__static_initialization_and_destruction_0(int, int)+0x65>
101352: 81 7d 0c ff ff 00 00 cmpl $0xffff,0xc(%ebp)
101359: 75 50 jne 1013ab <__static_initialization_and_destruction_0(int, int)+0x65>
10135b: c7 04 24 10 e0 10 00 movl $0x10e010,(%esp)
101362: e8 b5 64 00 00 call 10781c <gstl::HashMap<gstl::String, gstl::String>::HashMap()>
101367: c7 44 24 08 70 f8 10 movl $0x10f870,0x8(%esp)
10136e: 00
10136f: c7 44 24 04 10 e0 10 movl $0x10e010,0x4(%esp)
101376: 00
101377: c7 04 24 cc 7f 10 00 movl $0x107fcc,(%esp)
10137e: e8 c0 27 00 00 call 103b43 <__cxa_atexit>
101383: c7 04 24 1c e0 10 00 movl $0x10e01c,(%esp)
10138a: e8 b1 64 00 00 call 107840 <gstl::List<Tool*>::List()>
10138f: c7 44 24 08 70 f8 10 movl $0x10f870,0x8(%esp)
101396: 00
101397: c7 44 24 04 1c e0 10 movl $0x10e01c,0x4(%esp)
10139e: 00
10139f: c7 04 24 a6 80 10 00 movl $0x1080a6,(%esp)
1013a6: e8 98 27 00 00 call 103b43 <__cxa_atexit>
1013ab: c9 leave
1013ac: c3 ret
3. This HashMap is laying around somewhere as a global variable.. and guess what, the constructor of my HashMap calls "new":
Code: Select all
... /**
* Initializes the bucket array
*/
void initialize(uint32_t newBucketCount) {
this->bucketCount = newBucketCount;
this->bucketArray = new HashMapEntry<K, V>*[bucketCount];
for (uint32_t i = 0; i < newBucketCount; i++) {
this->bucketArray[i] = 0;
}
}
...
public:
/**
* Creates the HashMap with 128 buckets
*/
HashMap() {
initialize(128);
}...
Only the devil himself knows, why my implementation of
new (calling the memory allocator implicitly) did not fail in QEMU, but did so in BOCHS... I guess QEMU sets all the memory to 0, which caused some funny runtime accident allowing the allocator to do... whatever... i think I've fallen in love with objdump :'D
btw: yep, i guess i'll use bochs from now on.
also: how do you guys manage that? do you even initialize global constructors at all? disallow that somehow? or just take care to not use them accidently?