New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Call c++ global variables in nxtask_startup #1341
Conversation
It is an incorrect design to call C++ constructors or destructors from the OS in kernel mode (PROTECTED and KERNEL builds) or with interrupts disabled. Calling the constructors.destructors introduces new problems similar to those discussed in Issue #1263 and which I am working toward fixing in PR #1328 Executing the constructors/destructors in kernel mode is a security violation. Running the constructors/destructors with interrupts disabled is just wrong. What if they need to wait for an event in a busy loop? No user code should ever run with interrupts disabled: This change should not be done. You should consider contributing to the correct fix that does not introduce additional problems of this nature. I would recommend that this change not be merged is it is not correct. It is expedient... but it is wrong. That is forbidden in the INVIOLABLES.txt:
Let's do things right. There is also a bug already listed in the to-level TODO list (This is also Issue #1265 ):
|
Think of how this is done in Linux: Each task has a wrapper function called __start in crt0.S and will handle both constructors and destructors. And the first layer or exit logic is part of the C library. |
Look how I did the pthread startup function in PR #1328. This is EXACTLY the same issue. I created a user-space pthread_startup (NOT and OS startup function) in libs/libc/pthread/pthread_create.c. This is exactly the kind of user-space startup function that you need: It runs in user mode with interrupts enabled. |
nxtask_startup is the part of libc in PROTECTED and run in the user mode:
KERNEL mode doesn't go this path.
This patch move the construction inside nuttx.bin(FLAT build)/nuttx_user.bin(PROTECTED) to nxtask_startup. it's different from ELF binary problem.
To follow the Linux approach, the major change is the build system:
The same approach is workable for ELF binary. But how do we handle the builtin apps, do you have the idea to avoid nxtask_start in this case? |
@patacongo to indicate nxtask_startup isn't used in KERNEL build, I add the guard like this:
|
to follow the naming convention Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com> Change-Id: I3594d12a65e8cacea99bc295d622628304c3f9f8
0031690
to
1093077
Compare
to avoid the similar code spread around each application Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com> Change-Id: I8967d647eaf2ecae47f29f83e7fa322ef1b42a02
The KERNEL build already works this way. crt0.c currently exists only at ./arm/src/armv7-a/crt0.c |
I will go ahead and merge this change. I do not think it is a worthwhile change since it does not improve the OS architecture except in some special cases. So although I do not think it has value, I will go ahead and merge because neither can I find any of the most serious that I feared. Think of how much more we could accomplished if we worked together in a common roadmap to achieve the same end goals. We could do much more together that if you constantly go in a different direction. |
In the FLAT build, there is only one set constructors. It does not matter how many built-in tasks there are, the constructors only have to be called once. Each separately linked blob will have one set of C++ constructors and must have its C++ constructors called exactly once. Currently the C++ constructors may be initialized in many places under apps/: examples/elf/elf_main.c: up_cxxinitialize(); Since the constructors will always be called in nxtask_startup(), I think these are now all bugs. We should also get rid of all occurrences of up_cxxinitialize(). @xiaoxiang781216 apps/platform/gnu/ should be removed too. |
@xiaoxiang781216 I think this change then resolves Issue #1265. Is that correct? If so then that issue should be closed. |
---help--- | ||
The platform-specific logic includes support for initialization | ||
of static C++ instances for this architecture and for the selected | ||
toolchain (via up_cxxinitialize()). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@xiaoxiang781216 up_cxxinitialize() should be removed. cxx_initialize() is the only system level C++ initializer in the FLAT build.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here: apache/nuttx-apps#316
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Look how I did the pthread startup function in PR #1328. This is EXACTLY the same issue. I created a user-space pthread_startup (NOT and OS startup function) in libs/libc/pthread/pthread_create.c. This is exactly the kind of user-space startup function that you need: It runs in user mode with interrupts enabled.
The same approach is workable for ELF binary. But how do we handle the builtin apps, do you have the idea to avoid nxtask_start in this case?
In the FLAT build, there is only one set constructors. It does not matter how many built-in tasks there are, the constructors only have to be called once. Each separately linked blob will have one set of C++ constructors and must have its C++ constructors called exactly once.
Currently the C++ constructors may be initialized in many places under apps/:
examples/elf/elf_main.c: up_cxxinitialize();
examples/helloxx/helloxx_main.cxx: up_cxxinitialize();
examples/nxterm/nxterm_main.c: up_cxxinitialize();
graphics/nxwm/src/nxwm_main.cxx: up_cxxinitialize();
graphics/twm4nx/src/twm4nx_main.cxx: up_cxxinitialize();Since the constructors will always be called in nxtask_startup(), I think these are now all bugs. We should also get rid of all occurrences of up_cxxinitialize().
@xiaoxiang781216 apps/platform/gnu/ should be removed too.
Yes, the patch is here: apache/nuttx-apps#316
@xiaoxiang781216 I think this change then resolves Issue #1265. Is that correct? If so then that issue should be closed.
No, this patch just centralize the builtin(FLAT and PROTECTED) constructor in one place. I will provide a patch for ELF binary this week.
inited = 1; | ||
} | ||
#endif | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@xiaoxiang781216 Is this logic specific to the GNU compiler? I don't know how other C++ compilers provide C++ constructor data. It could work completely differently. I wonder if this does not belong in libs/libc/machine/*/gnu
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@xiaoxiang781216 Is this logic specific to the GNU compiler? I don't know how other C++ compilers provide C++ constructor data.
Not too specific as far as I know, compiler(gcc, clang, ceva) always put the constructor points in a special section.
It could work completely differently. I wonder if this does not belong in libs/libc/machine/*/gnu
Yes, if some compiler work differently, we need put this stuff into the compiler specific folder, but libc/compiler/gnu may better than libc/machine/*/gnu since how to invoke the constructor is only compiler specific not machine specific.
BTW, on the other hand, the exception unwind is the compiler and machine specific, so could you review this patch?
#1315.
The code can't even compile on x86/sim platform when c++ exception is enabled.
Summary
To avoid the similar code spread around the apps code space
Impact
Testing