ejolson
Posts: 8037
Joined: Tue Mar 18, 2014 11:47 am

Debugging Alignment Exceptions

Sun Aug 01, 2021 9:44 pm

I've been working on porting a program to the Pico which generates alignment errors due to dereferencing pointers as *(int *)p where p is an unaligned memory address. Using the SDK is there anyway to trap this kind of exception?

Alternatively, if I set up a full blown Pico debugging environment can I use gdb to find and debug these exceptions?

More information is at

viewtopic.php?p=1896286#p1896286

slimhazard
Posts: 42
Joined: Sat Apr 03, 2021 8:47 pm

Re: Debugging Alignment Exceptions

Sun Aug 01, 2021 10:23 pm

If I understand it right, the Cortex M0+ requires 4-byte alignment for "words", or 32-bit accesses, which is what you'll want here for int. So you can check:

Code: Select all

if ((p & 3) != 0) {
	/* ... handle misalignment ... */
}
2-byte alignment is required for "half-words", or 16-bit. So if you're working with (uint16_t *), which I believe is the same as (short *), then you'd do the same check but with (p & 1).

ejolson
Posts: 8037
Joined: Tue Mar 18, 2014 11:47 am

Re: Debugging Alignment Exceptions

Sun Aug 01, 2021 10:45 pm

slimhazard wrote:
Sun Aug 01, 2021 10:23 pm
If I understand it right, the Cortex M0+ requires 4-byte alignment for "words", or 32-bit accesses, which is what you'll want here for int. So you can check:

Code: Select all

if ((p & 3) != 0) {
	/* ... handle misalignment ... */
}
2-byte alignment is required for "half-words", or 16-bit. So if you're working with (uint16_t *), which I believe is the same as (short *), then you'd do the same check but with (p & 1).
That's right. Fixing the alignment is not so much the problem as the fact that there are 22K lines of code and the Pico just crashes when an exception happens without a stack trace to say where. Do you have a Pico probe with gdb installed? Would that solve the problem of debugging this?

trejan
Posts: 3588
Joined: Tue Jul 02, 2019 2:28 pm

Re: Debugging Alignment Exceptions

Sun Aug 01, 2021 10:51 pm

Cortex-M0 is very basic and only has a hard fault trap which everything uses. This means no easy fault registers to read to determine the fault reason. You need to examine the saved registers, the code PC is pointing at and the stack to work out why you ended up in the hard fault handler. Faulting inside the hard fault handler will lock up the CPU so careful with how you examine memory.

https://dmitry.gr/?r=05.Projects&proj=2 ... ltDispatch is a very neat hack which implements all of this and gives you back all the various trap types.

ejolson
Posts: 8037
Joined: Tue Mar 18, 2014 11:47 am

Re: Debugging Alignment Exceptions

Sun Aug 01, 2021 10:57 pm

trejan wrote:
Sun Aug 01, 2021 10:51 pm
Cortex-M0 is very basic and only has a hard fault trap which everything uses. This means no easy fault registers to read to determine the fault reason. You need to examine the saved registers, the code PC is pointing at and the stack to work out why you ended up in the hard fault handler. Faulting inside the hard fault handler will lock up the CPU so careful with how you examine memory.

https://dmitry.gr/?r=05.Projects&proj=2 ... ltDispatch is a very neat hack which implements all of this and gives you back all the various trap types.
Aha! That might be exactly what I've been looking for. Thanks!

kilograham
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 868
Joined: Fri Apr 12, 2019 11:00 am
Location: austin tx

Re: Debugging Alignment Exceptions

Mon Aug 02, 2021 12:08 am

Note you may want the recently added

Code: Select all

exception_set_exclusive_handler(HARDFAULT_EXCEPTION, some_handler)
to install it

ejolson
Posts: 8037
Joined: Tue Mar 18, 2014 11:47 am

Re: Debugging Alignment Exceptions

Mon Aug 02, 2021 4:58 am

kilograham wrote:
Mon Aug 02, 2021 12:08 am
Note you may want the recently added

Code: Select all

exception_set_exclusive_handler(HARDFAULT_EXCEPTION, some_handler)
to install it
I've downloaded the latest SDK and added

Code: Select all

#include <hardware/exception.h>
to my headers, regenerated with cmake but it can't find the header.

Any idea why and how to fix it?

ejolson
Posts: 8037
Joined: Tue Mar 18, 2014 11:47 am

Re: Debugging Alignment Exceptions

Mon Aug 02, 2021 5:02 am

ejolson wrote:
Mon Aug 02, 2021 4:58 am
kilograham wrote:
Mon Aug 02, 2021 12:08 am
Note you may want the recently added

Code: Select all

exception_set_exclusive_handler(HARDFAULT_EXCEPTION, some_handler)
to install it
I've downloaded the latest SDK and added

Code: Select all

#include <hardware/exception.h>
to my headers, regenerated with cmake but it can't find the header.

Any idea why and how to fix it?
Never mind. I guessed and discovered that

Code: Select all

    target_link_libraries(bbcbasic pico_stdlib hardware_exception)
in my CmakeLists.txt fixes it. Out of curiosity, does anyone know where is this documented?

ejolson
Posts: 8037
Joined: Tue Mar 18, 2014 11:47 am

Re: Debugging Alignment Exceptions

Mon Aug 02, 2021 5:41 am

ejolson wrote:
Mon Aug 02, 2021 5:02 am
ejolson wrote:
Mon Aug 02, 2021 4:58 am
kilograham wrote:
Mon Aug 02, 2021 12:08 am
Note you may want the recently added

Code: Select all

exception_set_exclusive_handler(HARDFAULT_EXCEPTION, some_handler)
to install it
I've downloaded the latest SDK and added

Code: Select all

#include <hardware/exception.h>
to my headers, regenerated with cmake but it can't find the header.

Any idea why and how to fix it?
Never mind. I guessed and discovered that

Code: Select all

    target_link_libraries(bbcbasic pico_stdlib hardware_exception)
in my CmakeLists.txt fixes it. Out of curiosity, does anyone know where is this documented?
Woohoo! It works! My proof of concept code

viewtopic.php?p=1896381#p1896381

prints SIGBUS when an hardware exception occurs and then returns to uf2 load and boot mode.

kilograham
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 868
Joined: Fri Apr 12, 2019 11:00 am
Location: austin tx

Re: Debugging Alignment Exceptions

Mon Aug 02, 2021 1:26 pm

ejolson wrote:
Mon Aug 02, 2021 5:02 am
Never mind. I guessed and discovered that

Code: Select all

    target_link_libraries(bbcbasic pico_stdlib hardware_exception)
in my CmakeLists.txt fixes it. Out of curiosity, does anyone know where is this documented?
https://datasheets.raspberrypi.org/pico ... -c-sdk.pdf section 2.2

ejolson
Posts: 8037
Joined: Tue Mar 18, 2014 11:47 am

Re: Debugging Alignment Exceptions

Sat Aug 07, 2021 3:36 am

kilograham wrote:
Mon Aug 02, 2021 1:26 pm
ejolson wrote:
Mon Aug 02, 2021 5:02 am
Never mind. I guessed and discovered that

Code: Select all

    target_link_libraries(bbcbasic pico_stdlib hardware_exception)
in my CmakeLists.txt fixes it. Out of curiosity, does anyone know where is this documented?
https://datasheets.raspberrypi.org/pico ... -c-sdk.pdf section 2.2
Thanks. I'm trying to become self-sufficient at this. Sorry it's going slow. I now have the m0FaultDispatch library linked in and my simple test case produces output that looks like

Code: Select all

This is the alignment test...
memcpy(&mem[0],&i,sizeof(int))
memset(&mem[0],0,4)
(int *)&mem[0]=0
memcpy(&mem[5],&i,sizeof(int))
memset(&mem[5],0,4)
(int *)&mem[5]=5
Data alignment fault sr = 0x21000000
R0  = 0x006ada66  R8  = 0x10007e94
R1  = 0x00000000  R9  = 0xffffffff
R2  = 0x006ada6a  R10 = 0xffffffff
R3  = 0x40054000  R11 = 0xffffffff
R4  = 0x00000005  R12 = 0x00000000
R5  = 0x20001af8  SP  = 0x20041fe8
R6  = 0x10007ed0  LR  = 0x1000112f
R7  = 0x10007eb8  PC  = 0x100005b2
 -> unaligned access to 0x20001afd
More information is at

viewtopic.php?p=1898840#p1898840

I found the faulting instruction in the align.dis file created by cmake, but the C source is not interspersed with that disassembly. Is there any way to display the source code intermixed in the disassembly file?

ejolson
Posts: 8037
Joined: Tue Mar 18, 2014 11:47 am

Re: Debugging Alignment Exceptions

Sat Aug 07, 2021 3:46 am

ejolson wrote:
Sat Aug 07, 2021 3:36 am
kilograham wrote:
Mon Aug 02, 2021 1:26 pm
ejolson wrote:
Mon Aug 02, 2021 5:02 am
Never mind. I guessed and discovered that

Code: Select all

    target_link_libraries(bbcbasic pico_stdlib hardware_exception)
in my CmakeLists.txt fixes it. Out of curiosity, does anyone know where is this documented?
https://datasheets.raspberrypi.org/pico ... -c-sdk.pdf section 2.2
Thanks. I'm trying to become self-sufficient at this. Sorry it's going slow. I now have the m0FaultDispatch library linked in and my simple test case produces output that looks like

Code: Select all

This is the alignment test...
memcpy(&mem[0],&i,sizeof(int))
memset(&mem[0],0,4)
(int *)&mem[0]=0
memcpy(&mem[5],&i,sizeof(int))
memset(&mem[5],0,4)
(int *)&mem[5]=5
Data alignment fault sr = 0x21000000
R0  = 0x006ada66  R8  = 0x10007e94
R1  = 0x00000000  R9  = 0xffffffff
R2  = 0x006ada6a  R10 = 0xffffffff
R3  = 0x40054000  R11 = 0xffffffff
R4  = 0x00000005  R12 = 0x00000000
R5  = 0x20001af8  SP  = 0x20041fe8
R6  = 0x10007ed0  LR  = 0x1000112f
R7  = 0x10007eb8  PC  = 0x100005b2
 -> unaligned access to 0x20001afd
More information is at

viewtopic.php?p=1898840#p1898840

I found the faulting instruction in the align.dis file created by cmake, but the C source is not interspersed with that disassembly. Is there any way to display the source code intermixed in the disassembly file?
Never mind, I managed by adding -g to CMAKE_C_FLAGS and then typing

Code: Select all

arm-none-eabi-objdump -S align.elf
Why doesn't align.dis already include the source code? Is there a better way?

User avatar
jahboater
Posts: 7312
Joined: Wed Feb 04, 2015 6:38 pm
Location: Wonderful West Dorset

Re: Debugging Alignment Exceptions

Sat Aug 07, 2021 9:38 am

ejolson wrote:
Sat Aug 07, 2021 3:36 am
I found the faulting instruction in the align.dis file created by cmake, but the C source is not interspersed with that disassembly. Is there any way to display the source code intermixed in the disassembly file?
For GCC version 7 or later, -fverbose-asm intermixes the original C source with the assembler.
It is extremely use for examining assembler output as you can just search for something unique in the C source line and go right there.
Its usually pretty accurate even with optimization, unless the code has been completely removed.

Code: Select all

gcc -Os -S -fverbose-asm hello.c -o hello.s

pica200
Posts: 281
Joined: Tue Aug 06, 2019 10:27 am

Re: Debugging Alignment Exceptions

Sat Aug 07, 2021 11:26 am

You can also take the address of the faulting instruction and run arm-none-eabi-addr2line with the elf file which gives you the exact source file with the line where the fault occurs.

kilograham
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 868
Joined: Fri Apr 12, 2019 11:00 am
Location: austin tx

Re: Debugging Alignment Exceptions

Sat Aug 07, 2021 1:46 pm

Note you should never need to add "-g" to C_FLAGS

pass `CMAKE_BUILD_TYPE=Debug` to cmake ... I'm sure that is documented :-) (everywhere CMake is found)

lurk101
Posts: 887
Joined: Mon Jan 27, 2020 2:35 pm
Location: Cumming, GA (US)

Re: Debugging Alignment Exceptions

Sat Aug 07, 2021 2:04 pm

kilograham wrote:
Sat Aug 07, 2021 1:46 pm
Note you should never need to add "-g" to C_FLAGS

pass `CMAKE_BUILD_TYPE=Debug` to cmake ... I'm sure that is documented :-) (everywhere CMake is found)
And what a pain that is. Having to type two dozen characters to switch to debug... brilliant!

ejolson
Posts: 8037
Joined: Tue Mar 18, 2014 11:47 am

Re: Debugging Alignment Exceptions

Sat Aug 07, 2021 3:10 pm

lurk101 wrote:
Sat Aug 07, 2021 2:04 pm
kilograham wrote:
Sat Aug 07, 2021 1:46 pm
Note you should never need to add "-g" to C_FLAGS

pass `CMAKE_BUILD_TYPE=Debug` to cmake ... I'm sure that is documented :-) (everywhere CMake is found)
And what a pain that is. Having to type two dozen characters to switch to debug... brilliant!
I count only 22 characters plus maybe a space for a separator, but if you count the caps-lock key that's more than two-dozen button presses. Will gdb on a Pico probe decode alignment exceptions and display a stack trace when they occur?

Given the way m0FaultDispatch can figure out the faulting instruction and reason, I think it could be extended to emulate the unaligned access byte by byte and then continue on to the next instruction. This would lose atomicity for unaligned reads and writes, but at least they would not cause the program to crash. Does such a functionality already exist somewhere?

trejan
Posts: 3588
Joined: Tue Jul 02, 2019 2:28 pm

Re: Debugging Alignment Exceptions

Sat Aug 07, 2021 3:38 pm

ejolson wrote:
Sat Aug 07, 2021 3:10 pm
Will gdb on a Pico probe decode alignment exceptions and display a stack trace when they occur?
The Cortex-M0+ core itself only has a hard fault exception and nothing else. m0FaultDispatch is a hack to get the other exceptions and gdb doesn't know anything about it.
ejolson wrote:
Sat Aug 07, 2021 3:10 pm
Given the way m0FaultDispatch can figure out the faulting instruction and reason, I think it could be extended to emulate the unaligned access byte by byte and then continue on to the next instruction.
You'd need to decode what the instruction is actually trying to do, replicate that, alter the exception frame and finally return. Nothing too difficult, just tedious to write.
ejolson wrote:
Sat Aug 07, 2021 3:10 pm
Does such a functionality already exist somewhere?
AFAIK no. Mindset is different for small microcontrollers as you're meant to tailor the code to that specific device.

lurk101
Posts: 887
Joined: Mon Jan 27, 2020 2:35 pm
Location: Cumming, GA (US)

Re: Debugging Alignment Exceptions

Sat Aug 07, 2021 3:50 pm

ejolson wrote:
Sat Aug 07, 2021 3:10 pm
Will gdb on a Pico probe decode alignment exceptions and display a stack trace when they occur?
Yes, but I'm not using picoprobe.

Code: Select all

#include "pico/stdlib.h"
#include "stdio.h"

static int unaligned(int v)
{
        return *((int*)v);
}

int main(void) {
    stdio_init_all();
    printf("%d\n", unaligned(0x20000001));
}

Code: Select all

pi@raspberrypi:~/pico-user/test/b $ g 0 test.elf
GNU gdb (Debian 8.2.1-2+b3) 8.2.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
...
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from test.elf...done.
isr_hardfault () at /home/pi/pico/pico-sdk/src/rp2_common/pico_standard_link/crt0.S:99
99      decl_isr_bkpt isr_hardfault
target halted due to debug-request, current mode: Thread 
xPSR: 0xf1000000 pc: 0x000000ee msp: 0x20041f00
target halted due to debug-request, current mode: Thread 
xPSR: 0xf1000000 pc: 0x000000ee msp: 0x20041f00
(gdb) load test.elf
Loading section .boot2, size 0x100 lma 0x10000000
Loading section .text, size 0x3f10 lma 0x10000100
Loading section .rodata, size 0xd60 lma 0x10004010
Loading section .binary_info, size 0x28 lma 0x10004d70
Loading section .data, size 0x260 lma 0x10004d98
Start address 0x100001e8, load size 20472
Transfer rate: 35 KB/sec, 3412 bytes/write.
(gdb) cont
Continuing.
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x0000012a msp: 0x20041f00

Thread 1 received signal SIGTRAP, Trace/breakpoint trap.
isr_hardfault () at /home/pi/pico/pico-sdk/src/rp2_common/pico_standard_link/crt0.S:99
99      decl_isr_bkpt isr_hardfault
(gdb) backtrace 
#0  isr_hardfault () at /home/pi/pico/pico-sdk/src/rp2_common/pico_standard_link/crt0.S:99
#1  <signal handler called>
#2  unaligned (v=v@entry=536870913) at /home/pi/pico-user/test/test.c:6
#3  0x1000036c in main () at /home/pi/pico-user/test/test.c:11
(gdb)
BTW. If the compiler can determine that you're doing unaligned access it will generate the proper byte per byte or halfword per halfword loads. Hint: Use the __packed__ attribute where applicable.

Code: Select all

return *((int*)0x20000001);
Would not crash!

kilograham
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 868
Joined: Fri Apr 12, 2019 11:00 am
Location: austin tx

Re: Debugging Alignment Exceptions

Sat Aug 07, 2021 6:25 pm

lurk101 wrote:
Sat Aug 07, 2021 2:04 pm
kilograham wrote:
Sat Aug 07, 2021 1:46 pm
Note you should never need to add "-g" to C_FLAGS

pass `CMAKE_BUILD_TYPE=Debug` to cmake ... I'm sure that is documented :-) (everywhere CMake is found)
And what a pain that is. Having to type two dozen characters to switch to debug... brilliant!
yes, but it is usually a single button click in any IDE or probably CMake GUI.

lurk101
Posts: 887
Joined: Mon Jan 27, 2020 2:35 pm
Location: Cumming, GA (US)

Re: Debugging Alignment Exceptions

Sat Aug 07, 2021 7:17 pm

kilograham wrote:
Sat Aug 07, 2021 6:25 pm
lurk101 wrote:
Sat Aug 07, 2021 2:04 pm
kilograham wrote:
Sat Aug 07, 2021 1:46 pm
Note you should never need to add "-g" to C_FLAGS

pass `CMAKE_BUILD_TYPE=Debug` to cmake ... I'm sure that is documented :-) (everywhere CMake is found)
And what a pain that is. Having to type two dozen characters to switch to debug... brilliant!
yes, but it is usually a single button click in any IDE or probably CMake GUI.
I've yet to find a suitable one!

ejolson
Posts: 8037
Joined: Tue Mar 18, 2014 11:47 am

Re: Debugging Alignment Exceptions

Sat Aug 07, 2021 7:47 pm

lurk101 wrote:
Sat Aug 07, 2021 7:17 pm
kilograham wrote:
Sat Aug 07, 2021 6:25 pm
lurk101 wrote:
Sat Aug 07, 2021 2:04 pm

And what a pain that is. Having to type two dozen characters to switch to debug... brilliant!
yes, but it is usually a single button click in any IDE or probably CMake GUI.
I've yet to find a suitable one!
My impression is most IDEs were designed for and by developers who still haven't figured out how to conveniently switch between different applications on their desktop, but let's not get off topic.

It seems you can add

set(CMAKE_BUILD_TYPE "Debug")

near the top of CMakeLists.txt and avoid any further button pressing or mouse clicking. However, even after that align.dis does not include the interspersed C code. As far as I can tell, I need to type

arm-none-eabi-objdump -S align.elf

to get an annotated disassembly. Even though it's more than two dozen characters, one can always cut and paste the required command from this post or alternatively add another checkbox to the IDE.

Is anyone up to writing the code to fix up unaligned memory accesses on the Pico? I see that m0FaultDispatch has an example of emulating a UDIV instruction so that might provide a pattern to follow.

lurk101
Posts: 887
Joined: Mon Jan 27, 2020 2:35 pm
Location: Cumming, GA (US)

Re: Debugging Alignment Exceptions

Sat Aug 07, 2021 8:32 pm

ejolson wrote:
Sat Aug 07, 2021 7:47 pm
Is anyone up to writing the code to fix up unaligned memory accesses on the Pico?
Why?

WestfW
Posts: 115
Joined: Tue Nov 01, 2011 9:56 pm

Re: Debugging Alignment Exceptions

Sun Aug 08, 2021 2:06 am

pass `CMAKE_BUILD_TYPE=Debug` to cmake ... I'm sure that is documented :-) (everywhere CMake is found)
And what a pain that is. Having to type two dozen characters to switch to debug... brilliant!
See also: https://github.com/raspberrypi/pico-sdk/issues/214 - AFAIK there is no reason not to specify "-g" for ALL builds. (object file size, perhaps (because of the extra debug info, not because of different code.) But I have trouble believing that anyone considers that an issue... (this issue was assigned a target; maybe it will actually happen.)

Is anyone up to writing the code to fix up unaligned memory accesses on the Pico?
It would be very "expensive", compared to fixing the source to use some sort of GETLONG() macro or function.
(does anyone have some nice optimized implementation of uint32_t GETLONG(__unalligned__ uint32*)? Seems like the sort of thing that would be annoying for C to optimize, especially WRT number of registers used...)

ejolson
Posts: 8037
Joined: Tue Mar 18, 2014 11:47 am

Re: Debugging Alignment Exceptions

Sun Aug 08, 2021 3:05 am

WestfW wrote:
Sun Aug 08, 2021 2:06 am
pass `CMAKE_BUILD_TYPE=Debug` to cmake ... I'm sure that is documented :-) (everywhere CMake is found)
And what a pain that is. Having to type two dozen characters to switch to debug... brilliant!
See also: https://github.com/raspberrypi/pico-sdk/issues/214 - AFAIK there is no reason not to specify "-g" for ALL builds. (object file size, perhaps (because of the extra debug info, not because of different code.) But I have trouble believing that anyone considers that an issue... (this issue was assigned a target; maybe it will actually happen.)

Is anyone up to writing the code to fix up unaligned memory accesses on the Pico?
It would be very "expensive", compared to fixing the source to use some sort of GETLONG() macro or function.
(does anyone have some nice optimized implementation of uint32_t GETLONG(__unalligned__ uint32*)? Seems like the sort of thing that would be annoying for C to optimize, especially WRT number of registers used...)
From what I can tell an unaligned read is accomplished by reading bytes and rotating them into whatever register you want. A write is just the other way around. Given the way the exception handler works, such emulation would be even slower for the Cortex-M0+ than usual.

Although not crashing when there is an alternative ensures greater reliability, the low cost of a Pico development board with relatively large amounts of RAM has led to a unique diversity of users. While engineers may favour creation of bespoke programs that obey alignment requirements, such limits may not be reasonable for hobbyists, students, scientists or all other users.

It's also worth noting Linux generally runs with support for unaligned access turned on for architectures such as ARMv6 where there is a choice. My understanding is the reason for this is because it is difficult to ensure all combinations of code paths in a complex program lead to aligned memory access and that not crashing is better.
Last edited by ejolson on Sun Aug 08, 2021 4:32 am, edited 2 times in total.

Return to “SDK”