diff --git a/miosix/_tools/processes_tests/exception_unwinding/CMakeLists.txt b/miosix/_tools/processes_tests/exception_unwinding/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ab938ed50658bdf656a6d953931d3d2913a1d13e
--- /dev/null
+++ b/miosix/_tools/processes_tests/exception_unwinding/CMakeLists.txt
@@ -0,0 +1,40 @@
+# Copyright (C) 2024 by Skyward
+#
+# This program is free software; you can redistribute it and/or
+# it under the terms of the GNU General Public License as published
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# As a special exception, if other files instantiate templates or use
+# macros or inline functions from this file, or you compile this file
+# and link it with other works to produce a work based on this file,
+# this file does not by itself cause the resulting work to be covered
+# by the GNU General Public License. However the source code for this
+# file must still be made available in accordance with the GNU
+# Public License. This exception does not invalidate any other
+# why a work based on this file might be covered by the GNU General
+# Public License.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>
+
+cmake_minimum_required(VERSION 3.16)
+
+project(ProcessesExamples C CXX ASM)
+
+# Set Miosix definitions and options
+add_compile_definitions($<$<COMPILE_LANGUAGE:C,CXX>:MIOSIX_SKIP_SETTINGS_EDIT>)
+set(MIOSIX_OPT_BOARD stm32f429zi_stm32f4discovery CACHE STRING "Target board")
+set(MIOSIX_LINKER_SCRIPT stm32_2m+stm32_2m+8m_xram.ld CACHE FILEPATH "Linker script")
+
+add_subdirectory(../../.. miosix EXCLUDE_FROM_ALL)
+include(LinkTarget)
+
+# Kernel level program
+add_executable(main main.cpp)
+miosix_link_target(main)
diff --git a/miosix/_tools/processes_tests/exception_unwinding/debugging_notes.md b/miosix/_tools/processes_tests/exception_unwinding/debugging_notes.md
new file mode 100644
index 0000000000000000000000000000000000000000..66828dabc4311887b366a8f4bc629a0405506c7e
--- /dev/null
+++ b/miosix/_tools/processes_tests/exception_unwinding/debugging_notes.md
@@ -0,0 +1,34 @@
+# When compiling with `clang`
+
+`__cxa_throw` gets called with:
+
+```
+__cxxabiv1::__cxa_throw (obj=0xd0002348, tinfo=0x801fa84 <typeinfo for int>, dest=0x0)
+```
+
+These 3 parameters are (from [The Secret Life of C++: Day 3: Exceptions](https://www.mit.edu/~sipb-iap/2004/inside-c/day3/exceptions.html)):
+
+- An exception object
+- A typeinfo for that object
+- A pointer to the destructor to call when we are done with that object.
+
+They are correct because:
+
+- The exception object address is returned from `__cxa_allocate_exception`, and by reading that address from memory the correct value (1) is found
+- The exception object is an `int`
+- There is no constructor
+
+`__cxa_throw` is defined in `miosix/_tools/compiler/gcc-9.2.0-mp3.2/gcc-9.2.0/libstdc++-v3/libsupc++/eh_throw.cc:75`.
+
+`__cxa_throw` calls `_Unwind_RaiseException` from `gcc-9.2.0/libgcc/config/arm/libunwind.S:356` but this is just a wrapper for `__gnu_Unwind_RaiseException` in `gcc-9.2.0/libgcc/unwind-arm-common.inc:429`.
+
+```
+__gnu_Unwind_RaiseException (ucbp=0xd00022f0, entry_vrs=0xd0001a74)
+```
+
+Where the parameters are:
+
+- `ucbp` is the pointer to the unwind control block, which contains information about the exception being raised. It is used to manage the state of the exception.
+- `entry_vrs` is the pointer to a structure that contains the virtual register set for pahse 2 of the unsinding process. This holds the state of the registers at the point where the exception was raised and is used to restore the state when transferring control to a catch block or cleanup code.
+
+In `__gnu_Unwind_RaiseException` the personality routing gets called through `UCB_PR_ADDR`.
diff --git a/miosix/_tools/processes_tests/exception_unwinding/how_to_debug_with_clang.md b/miosix/_tools/processes_tests/exception_unwinding/how_to_debug_with_clang.md
new file mode 100644
index 0000000000000000000000000000000000000000..9084095e3c6afb90f80affd938dedffdacef10e6
--- /dev/null
+++ b/miosix/_tools/processes_tests/exception_unwinding/how_to_debug_with_clang.md
@@ -0,0 +1,21 @@
+Compile and flash with:
+
+```shell
+cmake -DCMAKE_BUILD_TYPE=Debug -Bbuild -DCMAKE_TOOLCHAIN_FILE=../../../cmake/Toolchains/clang.cmake
+cmake --build build -j 16 --target main_program
+```
+
+Run OpenOCD:
+
+```shell
+openocd -f /home/alberton/Documents/CTO/miosix-kernel/miosix/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery/stm32f4discovery.cfg
+```
+
+Run `gdb`:
+
+```shell
+gdb build/main.elf
+(gdb) target remote :3333
+```
+
+`monitor reset halt` to reset the board.
diff --git a/miosix/_tools/processes_tests/exception_unwinding/main.cpp b/miosix/_tools/processes_tests/exception_unwinding/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6b62dfc0a1c8ee202af408270f2c5ddbc074be32
--- /dev/null
+++ b/miosix/_tools/processes_tests/exception_unwinding/main.cpp
@@ -0,0 +1,16 @@
+#include <cstdio>
+
+void __attribute__((noinline)) f()
+{
+   throw 1;
+}
+
+int main() try {
+    puts("in");
+    f();
+    puts("out");
+    return 0;
+} catch(int& e) {
+    puts("exc");
+    return e;
+}
diff --git a/miosix/_tools/processes_tests/extern_const/CMakeLists.txt b/miosix/_tools/processes_tests/extern_const/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..749fddec2a2b048cddacf58e50f4a5e9e710c111
--- /dev/null
+++ b/miosix/_tools/processes_tests/extern_const/CMakeLists.txt
@@ -0,0 +1,42 @@
+# Copyright (C) 2024 by Skyward
+#
+# This program is free software; you can redistribute it and/or
+# it under the terms of the GNU General Public License as published
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# As a special exception, if other files instantiate templates or use
+# macros or inline functions from this file, or you compile this file
+# and link it with other works to produce a work based on this file,
+# this file does not by itself cause the resulting work to be covered
+# by the GNU General Public License. However the source code for this
+# file must still be made available in accordance with the GNU
+# Public License. This exception does not invalidate any other
+# why a work based on this file might be covered by the GNU General
+# Public License.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>
+
+cmake_minimum_required(VERSION 3.16)
+
+project(ProcessesExamples C CXX ASM)
+
+# Set Miosix definitions and options
+add_compile_definitions($<$<COMPILE_LANGUAGE:C,CXX>:MIOSIX_SKIP_SETTINGS_EDIT>)
+set(MIOSIX_OPT_BOARD stm32f767zi_nucleo CACHE STRING "Target board")
+set(MIOSIX_LINKER_SCRIPT stm32_2m+384k_ram_processes.ld CACHE FILEPATH "Linker script")
+
+add_subdirectory(../../.. miosix EXCLUDE_FROM_ALL)
+add_subdirectory(../../../libsyscalls libsyscalls EXCLUDE_FROM_ALL)
+
+include(LinkTarget)
+include(AddProcess)
+
+# Processes
+miosix_add_process(main main.cpp)
diff --git a/miosix/_tools/processes_tests/extern_const/main.cpp b/miosix/_tools/processes_tests/extern_const/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d61046532888b4b6c47b6fc860fa80a5654221b0
--- /dev/null
+++ b/miosix/_tools/processes_tests/extern_const/main.cpp
@@ -0,0 +1,14 @@
+extern const int aRodata;
+extern int aData;
+const char str[] = "Hello world\n";
+
+int get1() { return aRodata; }
+
+int get2() { return aData; }
+
+const char *get3() { return str; }
+
+int main()
+{
+    return 0;
+}
diff --git a/miosix/_tools/processes_tests/processes_patch_recap.md b/miosix/_tools/processes_tests/processes_patch_recap.md
new file mode 100644
index 0000000000000000000000000000000000000000..36b246b506a105b64348a6c2510fecf3b5b54525
--- /dev/null
+++ b/miosix/_tools/processes_tests/processes_patch_recap.md
@@ -0,0 +1,48 @@
+## `extern const`
+
+In processes compiled with GCC 4.7.3:
+
+- stuff in `.data` are accessed from the GOT, which is OK
+- strings in `.rodata` are accessed PC-relative, which is OK
+- consts in `.rodata` are accessed from the GOT, which is WRONG! (more on that later when pointer are involved, though)
+
+Here's an example:
+
+```cpp
+extern const int aRodata;
+extern int aData;
+const char str[]="Hello world\n";
+
+int get1() { return aRodata; }
+int get2() { return aData; }
+const char *get3() { return str; }
+```
+
+Compiled with `arm-miosix-eabi-gcc -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base -O2 -S processes.c`:
+
+```asm
+get1:
+	ldr	r3, .L3
+	ldr	r3, [r9, r3]
+	ldr	r0, [r3]
+	bx	lr
+
+get2:
+	ldr	r3, .L6
+	ldr	r3, [r9, r3]
+	ldr	r0, [r3]
+	bx	lr
+
+
+get3:
+	ldr	r0, .L9
+.LPIC0:
+	add	r0, pc
+	bx	lr
+```
+
+`get1()` is the wrong one, of course.
+
+What usually masks the issue is constant folding. Unless it's an extern const the value gets folded and the problem does not arise.
+
+Solution: The previous patch relied on a GCC function, `decl_readonly_section()` to check whether the global variable to be loaded is const or not, but that function missed a few cases, so a dedicated function, the `miosix_processes_ref_demux()` function was added in `arm.c`. This new function handles the corner cases better, and also allows to fix some of the next issues.