Skip to content
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

K_KERNEL_STACK_MEMBER causes linker error when used with picolibc and dynamic memory allocation in C++ #57899

Closed
r2r0 opened this issue May 15, 2023 · 6 comments · Fixed by #58012
Assignees
Labels
area: C++ area: Kernel area: picolibc Picolibc C Standard Library bug The issue is a bug, or the PR is fixing a bug priority: medium Medium impact/importance bug

Comments

@r2r0
Copy link
Member

r2r0 commented May 15, 2023

Describe the bug
When you try to allocate structure/class with K_KERNEL_STACK_MEMBER as its member and you have enabled HW_STACK_PROTECTION and picolibc then there is observed a linker error as below.
When newlib is used or HW_STACK_PROTECTION is disabled then the same application is built without problems.

To Reproduce
Code:

#include <zephyr/kernel.h>
#include <memory>

struct ThreadStack
{
	K_KERNEL_STACK_MEMBER(threadStack, 1024) {};
};

int main(void)
{
	{
		auto ptr = std::make_unique<ThreadStack>();
	}

	return 0;
}

Configuration:

CONFIG_CPP=y
CONFIG_CPP_MAIN=y
CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=4096
#CONFIG_NEWLIB_LIBC=y
CONFIG_PICOLIBC=y

CONFIG_STD_CPP17=y
CONFIG_GLIBCXX_LIBCPP=y

CONFIG_ARM_MPU=y
CONFIG_HW_STACK_PROTECTION=y

Build command (the same for nrf52840_mdk, npcx7m6fb_evb or any other platform with HW stack protection capability):

west build -p always -b nucleo_wb55rg  .

Expected behavior
Application should build without errors.

Impact
showstopper

Logs and console output

/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: /opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/../../picolibc/arm-zephyr-eabi/lib/thumb/v7e-m/nofp/libc.a(nano-malloc-memalign.c.o): in function `memalign':
nano-malloc-memalign.c:(.text.memalign+0x0): multiple definition of `aligned_alloc'; zephyr/lib/libc/common/liblib__libc__common.a(malloc.c.obj):/home/hid/aurora/zephyr/lib/libc/common/source/stdlib/malloc.c:138: first defined here
/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: /opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/../../picolibc/arm-zephyr-eabi/lib/thumb/v7e-m/nofp/libc.a(nano-malloc-free.c.o): in function `free':
nano-malloc-free.c:(.text.free+0x0): multiple definition of `free'; zephyr/lib/libc/common/liblib__libc__common.a(malloc.c.obj):/home/hid/aurora/zephyr/lib/libc/common/source/stdlib/malloc.c:223: first defined here
/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: /opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/../../picolibc/arm-zephyr-eabi/lib/thumb/v7e-m/nofp/libc.a(nano-malloc-malloc.c.o): in function `malloc':
nano-malloc-malloc.c:(.text.malloc+0x0): multiple definition of `malloc'; zephyr/lib/libc/common/liblib__libc__common.a(malloc.c.obj):/home/hid/aurora/zephyr/lib/libc/common/source/stdlib/malloc.c:119: first defined here
/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: /opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/../../picolibc/arm-zephyr-eabi/lib/thumb/v7e-m/nofp/libc.a(libc_picolib_picosbrk.c.o): in function `sbrk':
picosbrk.c:(.text.sbrk+0x2c): undefined reference to `__heap_start'
/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: picosbrk.c:(.text.sbrk+0x30): undefined reference to `__heap_end'
/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: /opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/../../picolibc/arm-zephyr-eabi/lib/thumb/v7e-m/nofp/libc.a(libc_picolib_picosbrk.c.o):(.data.brk+0x0): undefined reference to `__heap_start'
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

Environment (please complete the following information):

  • OS: Linux
  • Toolchain Zephyr SDK 0.16.1 (the same effect on 0.16.0)
  • a4341bb
@r2r0 r2r0 added the bug The issue is a bug, or the PR is fixing a bug label May 15, 2023
@jgl-meta jgl-meta added the priority: medium Medium impact/importance bug label May 16, 2023
@keith-packard
Copy link
Collaborator

This is somehow pulling in the 'memalign' function, which is not part of the common C library api. This causes the linker to pull in the picolibc internal malloc implementation which no longer works. What is using memalign()?

@keith-packard
Copy link
Collaborator

ah, I wonder if the compiler is using memalign internally? I'll provide a PR that you can review to see if it fixes the problem.

keith-packard added a commit to keith-packard/zephyr that referenced this issue May 17, 2023
Memalign is another name for the posix aligned_alloc function, although it
has weaker restrictions on the relationship between the alignment and size.

memalign appears to be used internally by the G++, so we need to provide an
implementation of this when using C++, even though it's not part of the
Zephyr C library API.

Closes: zephyrproject-rtos#57899

Signed-off-by: Keith Packard <[email protected]>
keith-packard added a commit to keith-packard/zephyr that referenced this issue May 18, 2023
Memalign is another name for the posix aligned_alloc function, although it
has weaker restrictions on the relationship between the alignment and size.

memalign appears to be used internally by the G++, so we need to provide an
implementation of this when using that compiler, even though it's not part
of the Zephyr C library API.

Closes: zephyrproject-rtos#57899

Signed-off-by: Keith Packard <[email protected]>
@keith-packard
Copy link
Collaborator

keith-packard commented May 18, 2023

@cfriedt encouraged me to write a test in #58012, so I've copied your code from above and stuffed it into the existing libcxx test case, which already required c++ 17.

keith-packard added a commit to keith-packard/zephyr that referenced this issue May 18, 2023
Memalign is another name for the posix aligned_alloc function, although it
has weaker restrictions on the relationship between the alignment and size.

memalign() is used internally by the libstdc++ when built for 'newlib'
targets (which includes picolibc) instead of aligned_alloc() due to a bug
in gcc, so we need to provide an implementation of this when using that
library, even though it's not part of the Zephyr C library API.

When a fix for the libstdc++ is merged upstream and can be consider a
reasonable dependency for Zephyr, this work-around can be removed.

Closes: zephyrproject-rtos#57899

Signed-off-by: Keith Packard <[email protected]>
keith-packard added a commit to keith-packard/zephyr that referenced this issue May 19, 2023
Memalign is another name for the posix aligned_alloc function, although it
has weaker restrictions on the relationship between the alignment and size.

memalign() is used internally by the libstdc++ when built for 'newlib'
targets (which includes picolibc) instead of aligned_alloc() due to a bug
in gcc, so we need to provide an implementation of this when using that
library, even though it's not part of the Zephyr C library API.

When a fix for the libstdc++ is merged upstream and can be consider a
reasonable dependency for Zephyr, this work-around can be removed.

Closes: zephyrproject-rtos#57899

Signed-off-by: Keith Packard <[email protected]>
keith-packard added a commit to keith-packard/zephyr that referenced this issue Jul 6, 2023
Memalign is another name for the posix aligned_alloc function, although it
has weaker restrictions on the relationship between the alignment and size.

memalign() is used internally by the libstdc++ when built for 'newlib'
targets (which includes picolibc) instead of aligned_alloc() due to a bug
in gcc, so we need to provide an implementation of this when using that
library, even though it's not part of the Zephyr C library API.

When a fix for the libstdc++ is merged upstream and can be consider a
reasonable dependency for Zephyr, this work-around can be removed.

Closes: zephyrproject-rtos#57899

Signed-off-by: Keith Packard <[email protected]>
keith-packard added a commit to keith-packard/zephyr that referenced this issue Jul 10, 2023
Memalign is another name for the posix aligned_alloc function, although it
has weaker restrictions on the relationship between the alignment and size.

memalign() is used internally by the libstdc++ when built for 'newlib'
targets (which includes picolibc) instead of aligned_alloc() due to a bug
in gcc, so we need to provide an implementation of this when using that
library, even though it's not part of the Zephyr C library API.

When a fix for the libstdc++ is merged upstream and can be consider a
reasonable dependency for Zephyr, this work-around can be removed.

Closes: zephyrproject-rtos#57899

Signed-off-by: Keith Packard <[email protected]>
keith-packard added a commit to keith-packard/zephyr that referenced this issue Jul 13, 2023
Memalign is another name for the posix aligned_alloc function, although it
has weaker restrictions on the relationship between the alignment and size.

memalign() is used internally by the libstdc++ when built for 'newlib'
targets (which includes picolibc) instead of aligned_alloc() due to a bug
in gcc, so we need to provide an implementation of this when using that
library, even though it's not part of the Zephyr C library API.

When a fix for the libstdc++ is merged upstream and can be consider a
reasonable dependency for Zephyr, this work-around can be removed.

Closes: zephyrproject-rtos#57899

Signed-off-by: Keith Packard <[email protected]>
keith-packard added a commit to keith-packard/zephyr that referenced this issue Jul 17, 2023
Memalign is another name for the posix aligned_alloc function, although it
has weaker restrictions on the relationship between the alignment and size.

memalign() is used internally by the libstdc++ when built for 'newlib'
targets (which includes picolibc) instead of aligned_alloc() due to a bug
in gcc, so we need to provide an implementation of this when using that
library, even though it's not part of the Zephyr C library API.

When a fix for the libstdc++ is merged upstream and can be consider a
reasonable dependency for Zephyr, this work-around can be removed.

Closes: zephyrproject-rtos#57899

Signed-off-by: Keith Packard <[email protected]>
@github-actions
Copy link

This issue has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this issue will automatically be closed in 14 days. Note, that you can always re-open a closed issue at any time.

@github-actions github-actions bot added the Stale label Jul 18, 2023
@cfriedt cfriedt removed the Stale label Jul 18, 2023
@cfriedt
Copy link
Member

cfriedt commented Jul 18, 2023

@keith-packard - any thoughts here?

@keith-packard
Copy link
Collaborator

@keith-packard - any thoughts here?

This is closed by #58012 which needs another review -- the underlying issue is a bug in gcc which uses memalign instead of aligned_alloc when built for newlib or picolibc. If you'd be up for reviewing that and helping get it merged, we could close this bug.

keith-packard added a commit to keith-packard/zephyr that referenced this issue Jul 18, 2023
Memalign is another name for the posix aligned_alloc function, although it
has weaker restrictions on the relationship between the alignment and size.

memalign() is used internally by the libstdc++ when built for 'newlib'
targets (which includes picolibc) instead of aligned_alloc() due to a bug
in gcc, so we need to provide an implementation of this when using that
library, even though it's not part of the Zephyr C library API.

When a fix for the libstdc++ is merged upstream and can be consider a
reasonable dependency for Zephyr, this work-around can be removed.

Closes: zephyrproject-rtos#57899

Signed-off-by: Keith Packard <[email protected]>
keith-packard added a commit to keith-packard/zephyr that referenced this issue Aug 7, 2023
Memalign is another name for the posix aligned_alloc function, although it
has weaker restrictions on the relationship between the alignment and size.

memalign() is used internally by the libstdc++ when built for 'newlib'
targets (which includes picolibc) instead of aligned_alloc() due to a bug
in gcc, so we need to provide an implementation of this when using that
library, even though it's not part of the Zephyr C library API.

When a fix for the libstdc++ is merged upstream and can be consider a
reasonable dependency for Zephyr, this work-around can be removed.

Closes: zephyrproject-rtos#57899

Signed-off-by: Keith Packard <[email protected]>
keith-packard added a commit to keith-packard/zephyr that referenced this issue Aug 10, 2023
Memalign is another name for the posix aligned_alloc function, although it
has weaker restrictions on the relationship between the alignment and size.

memalign() is used internally by the libstdc++ when built for 'newlib'
targets (which includes picolibc) instead of aligned_alloc() due to a bug
in gcc, so we need to provide an implementation of this when using that
library, even though it's not part of the Zephyr C library API.

When a fix for the libstdc++ is merged upstream and can be consider a
reasonable dependency for Zephyr, this work-around can be removed.

Closes: zephyrproject-rtos#57899

Signed-off-by: Keith Packard <[email protected]>
nashif pushed a commit that referenced this issue Aug 10, 2023
Memalign is another name for the posix aligned_alloc function, although it
has weaker restrictions on the relationship between the alignment and size.

memalign() is used internally by the libstdc++ when built for 'newlib'
targets (which includes picolibc) instead of aligned_alloc() due to a bug
in gcc, so we need to provide an implementation of this when using that
library, even though it's not part of the Zephyr C library API.

When a fix for the libstdc++ is merged upstream and can be consider a
reasonable dependency for Zephyr, this work-around can be removed.

Closes: #57899

Signed-off-by: Keith Packard <[email protected]>
umarnisar92 pushed a commit to nisarumar/zephyr that referenced this issue Aug 15, 2023
Memalign is another name for the posix aligned_alloc function, although it
has weaker restrictions on the relationship between the alignment and size.

memalign() is used internally by the libstdc++ when built for 'newlib'
targets (which includes picolibc) instead of aligned_alloc() due to a bug
in gcc, so we need to provide an implementation of this when using that
library, even though it's not part of the Zephyr C library API.

When a fix for the libstdc++ is merged upstream and can be consider a
reasonable dependency for Zephyr, this work-around can be removed.

Closes: zephyrproject-rtos#57899

Signed-off-by: Keith Packard <[email protected]>
meshium pushed a commit to meshium/zephyr that referenced this issue Aug 16, 2023
Memalign is another name for the posix aligned_alloc function, although it
has weaker restrictions on the relationship between the alignment and size.

memalign() is used internally by the libstdc++ when built for 'newlib'
targets (which includes picolibc) instead of aligned_alloc() due to a bug
in gcc, so we need to provide an implementation of this when using that
library, even though it's not part of the Zephyr C library API.

When a fix for the libstdc++ is merged upstream and can be consider a
reasonable dependency for Zephyr, this work-around can be removed.

Closes: zephyrproject-rtos#57899

Signed-off-by: Keith Packard <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: C++ area: Kernel area: picolibc Picolibc C Standard Library bug The issue is a bug, or the PR is fixing a bug priority: medium Medium impact/importance bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants