eclipse-threadx / threadx

Eclipse ThreadX is an advanced real-time operating system (RTOS) designed specifically for deeply embedded applications.
https://github.com/eclipse-threadx/rtos-docs/blob/main/rtos-docs/threadx/index.md
MIT License
2.87k stars 782 forks source link

Unaligned writes are not allowed with gcc ubsan (-fsanitize=undefined), this fails on 6.1.8 with ports/linux/gnu #218

Open owbear opened 1 year ago

owbear commented 1 year ago

https://github.com/azure-rtos/threadx/blob/b42c5acd8b9b1eb156c25e0b18c82beecfc033a1/ports/linux/gnu/src/tx_thread_stack_build.c#L131

The write here gives me an error regarding unaligned writes. memset() works

goldscott commented 1 year ago

You can ignore this. The stack is aligned previously - https://github.com/azure-rtos/threadx/blob/b42c5acd8b9b1eb156c25e0b18c82beecfc033a1/common/src/tx_thread_create.c#L132

owbear commented 1 year ago

A bit more context here: in the linux/gnu port tx_thread_stack_ptr is always unaligned as it is tx_thread_stack_end-8:

/* Setup a fake thread stack pointer.   */
thread_ptr -> tx_thread_stack_ptr =  (VOID *) (((CHAR *) thread_ptr -> tx_thread_stack_end) - 8);

/* Clear the first word of the stack.  */
*(((ULONG *) thread_ptr -> tx_thread_stack_ptr) - 1) =  0;
goldscott commented 1 year ago

Hi @owbear - my previous comment is only relevant if TX_ENABLE_STACK_CHECKING is defined. When this symbol is defined, ThreadX ensures that the stack pointer and stack size are aligned, as well as some runtime checking during context switches to check for stack overflows.

If not using TX_ENABLE_STACK_CHECKING, it is the developer's responsibility to ensure that the stack is aligned.

owbear commented 1 year ago

Hi Scott! TX_ENABLE_STACK_CHECKING fails in a different way with ubsan enabled using ports/linux/gnu:

Starting program: arch/native/radiohub 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0xf4affb40 (LWP 37588)]
[New Thread 0xf3effb40 (LWP 37589)]
[New Thread 0xf36feb40 (LWP 37590)]
/home/gotber/src/radiohub/code-review/env/threadx/common/src/tx_thread_system_resume.c:108:5: runtime error: load of misaligned address 0x56815217 for type 'ULONG', which requires 4 byte alignment
0x56815217: note: pointer points here
 ef ef ef ef 00  00 00 00 ef ef ef ef ef  ef ef ef ef ef ef ef ef  d8 60 81 56 ee ee ff ff  00 00 00
             ^ 
[Thread 0xf36feb40 (LWP 37590) exited]
[Thread 0xf4affb40 (LWP 37588) exited]
[Thread 0xf7012440 (LWP 37584) exited]
[Inferior 1 (process 37584) exited with code 01]
(gdb) l env/threadx/common/src/tx_thread_system_resume.c:108
103 
104 
105 #ifdef TX_ENABLE_STACK_CHECKING
106 
107     /* Check this thread's stack.  */
108     TX_THREAD_STACK_CHECK(thread_ptr)
109 #endif
110 
111     /* Lockout interrupts while the thread is being resumed.  */
112     TX_DISABLE

This misaligned access is in TX_THREAD_STACK_CHECK when it tries to load a 4-byte word from thread_ptr->tx_thread_stack_highest_ptr - 1

    if (*(((ULONG *) (thread_ptr) -> tx_thread_stack_highest_ptr) - 1) != TX_STACK_FILL)
owbear commented 1 year ago

That misalignment could be resolve with memcmp()

    static ULONG tx_stack_fill = TX_STACK_FILL;
    if (0 != memcmp(&tx_stack_fill, (thread_ptr)->tx_thread_stack_highest_ptr - 1, sizeof tx_stack_fill))