0

We have a multi-threaded c++ app compiled with g++ running on an embedded powerpc. To memory leak test this in a continuous integration test we've created a heap analyzer that gets loaded with ld_preload.

We'd like to guarantee that a function in the ld_preloaded module gets called before anything else happens (including creation of static objects etc...). Even more crucially we'd like to have another function that gets called right before the process exits so the heap analyzer can output its results. The problem we see is that a vector in our application is being created at global file scope before anything happens in our ld_preloaded module. The vector grows in size within main. At shutdown the destructor function in our preloaded module is called before the vector is destroyed.

Is there any way we can code a preloaded module to run a function before anything else and after everything else? We've tried using __attribute__((constructor)) and destructor without success.

Returning to the question title, I'm beginning to suspect that ld only looks in the preloaded module when resolving symbols for subsequent module loads. It doesn't actually load the preloaded module first. Can anyone shed any light on this for us?

Shafik Yaghmour
  • 143,425
  • 33
  • 399
  • 682
Fenster34
  • 416
  • 4
  • 10

1 Answers1

1

Originally, you would have no control over the order of constructors from different translation units. So, this extends to shared libraries as well.

However, newer versions of GCC support applying a priority parameter to the constructor attribute which should allow you some control over when your specified function will run in relation to other global constructors. The default priority when not specified is the maximum priority value. So any priority level you set below that should make your constructor run before them, and your destructor after them.

static int initialize () __attribute__((constructor(101)));
static int deinitialize () __attribute__((destructor(101)));

static int initialize () {
    puts("initialized");
}

static int deinitialize () {
    puts("deinitialized");
}

101 appears to be the lowest priority level allowed to be specified. 65535 is the highest. Lower numbers are executed first.

jxh
  • 64,506
  • 7
  • 96
  • 165
  • Unfortunatly this didn't have any affect. Further reading seems to suggest there's a never ending quest for the real entry point to a c++ app. – Fenster34 Aug 09 '12 at 20:32
  • 1
    Sorry it didn't work out. I can only suggest a workaround for you then. If you dynamically allocate your heap analyzer instead, it will never be destroyed. If it maintains its state in a memory mapped file, you can analyze the file later when the program ends. – jxh Aug 10 '12 at 01:51
  • Thats a great idea as its always guarenteed to work. We've opted to modify our code to avoid the issue but i'll record this as a future enhancement. Thanks – Fenster34 Aug 10 '12 at 21:25