__attribute__((constructor (200)) does not seem to work with Teensy 4.1

Status
Not open for further replies.

markster

New member
I recently purchased a Teensy 4.1 and am porting an application that heavily leverages constructor attributes. When running the following application under LInux, this snippet:

Code:
#include <stdio.h>

int foo;

int main(int argc, char *argv[])
{
	printf("foo is %d\n", foo);
}

void __attribute__((constructor (200))) init_foo(void)
{
	foo = 5;
}

Compiles and produces the following (expected output)

Code:
[markster@portamarko ~]$ gcc -o footest footest.c
[markster@portamarko ~]$ ./footest 
foo is 5
[markster@portamarko ~]$

That is, the funciton "init_foo" is called before main.

However, running a similar snippet of code under teensyduino (or using Makefiles):

Code:
int foo;

void setup() {
  while (!Serial);
  Serial.print("foo has the value ");
  Serial.println(foo);
}

// the loop routine runs over and over again forever:
void loop() {
}

void __attribute__((constructor (200))) init_foo(void)
{
  foo = 5;
}

Produces the incorrect output:

Code:
foo has the value 0

Any thoughts on what I need to do to get the constructors to be called?

Mark
 
Don't ask me why but it works without the priority argument. I.e.,

Code:
void __attribute__((constructor )) init_foo(void)
{
  foo = 5;
}

Are you sure that this is even supposed to work in c++ code? Seems to be relevant for C only?
 
Don't ask me why but it works without the priority argument. I.e.,

Code:
void __attribute__((constructor )) init_foo(void)
{
  foo = 5;
}

Are you sure that this is even supposed to work in c++ code? Seems to be relevant for C only?

Luni,

Thank you so much for the prompt reply. I can confirm your results. In my case, the code I am porting over is in C, but has the same result.

Based on your idea, I copied two directory trees from arduino_build to compare the binaries being built with and without priority. Using "objdump -t" on each object file and comparing the results, I see the following:

Code:
[markster@portamarko xfs]$ diff -uNr ~/without.txt ~/with.txt 
--- /home/markster/without.txt	2021-02-03 07:24:15.363077354 -0600
+++ /home/markster/with.txt	2021-02-03 07:24:07.905046480 -0600
@@ -1,5 +1,5 @@
 
-arduino_without_priority/sketch/Blink.ino.cpp.o:     file format elf32-little
+arduino_with_priority/sketch/Blink.ino.cpp.o:     file format elf32-little
 
 SYMBOL TABLE:
 00000000 l    df *ABS*	00000000 Blink.ino.cpp
@@ -14,8 +14,8 @@
 00000000 l    d  .text.startup._Z8init_foov	00000000 .text.startup._Z8init_foov
 00000000 l       .text.startup._Z8init_foov	00000000 $t
 00000008 l       .text.startup._Z8init_foov	00000000 $d
-00000000 l    d  .init_array	00000000 .init_array
-00000000 l       .init_array	00000000 $d
+00000000 l    d  .init_array.00200	00000000 .init_array.00200
+00000000 l       .init_array.00200	00000000 $d
 00000000 l    d  .bss.foo	00000000 .bss.foo
 00000000 l       .bss.foo	00000000 $d
 00000000 l    d  .rodata.str1.4	00000000 .rodata.str1.4
[markster@portamarko xfs]$

So, importantly, we can see it's going from .init_array to .init_array.00200. With a quick scan of the linker script, it doesn't appear that there is a KEEP for things with stuff after init_array, so I added this line to the linker script:

Code:
               KEEP (*(.init_array.*))

and voila, my constructors run. However, I am not sure if this should be differently in order to ensure they are placed in the order of priority. Any thoughts?

Mark
 
Interesting! However, linker scripts are definitely not my core competence. But I'm sure someone knowing more about this stuff will jump in to help.
 
Status
Not open for further replies.
Back
Top