-
Notifications
You must be signed in to change notification settings - Fork 3k
Optimise fault handler assembly #12824
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
Conversation
@kjbracey-arm, thank you for your changes. |
cad2be9
to
dce3712
Compare
LDR R1,[R3] | ||
BL mbed_fault_handler | ||
MOVS R1,R7 | ||
SUBS R1,#21*4 |
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.
what do we do here with substract, can you add a comment?
Is this similar what we do on line 99 - ADS to R1 value 48
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.
That's rewinding R7 back to the start of the fault context structure. I'm about to change it to just a reload of the address constant anyway - that's simpler once I've killed an unnecessary pointer indirection.
The other one was skipping over saved floating-point registers. (R1 was the stack pointer at that point, here it's preparing the second parameter for mbed_fault_handler)
MOVS R1,R6 | ||
LSRS R6,R4,#9 ; Check for if STK was aligned by checking bit-9 in xPSR value | ||
BCC Fault_Handler_Continue1 | ||
ADDS R1,#0x4 |
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.
Also here: can we comment on this addition or its me who does not see it before going into all instructions prior this one?
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.
That's performing the 8-byte stack alignment referenced (or at least hinted at) in the comment above.
Corrected addressing of stack frame if it's on the Main Stack - needed |
CI restarted |
early note: GCC failed I found one error at least: |
Test run: FAILEDSummary: 2 of 3 test jobs failed Failed test jobs:
|
My bad - botched rebase of work originally done on a fork. |
Fixed. mbed_fault_handler.h moved into (Although - shouldn't it be public? Is |
|
Travis is failing still. |
3ea954f
to
12d8915
Compare
Tidy up formatting, and make all 3 toolchain versions more consistent, for ease of diffing and transferring changes between them.
It's never been implemented for Cortex-A. You'd need a separate except.S, and for the targets to set their vector tables up to send data aborts etc there. At the minute all Cortex-A targets have their own private exception handlers that just halt the system, as far as I can tell. This change at least gives a structure they could pass to Probably could refine it a bit to make the "application" part of the context common (R0-R12,SP,LR,PC,PSR) - the A and M architectures only differ in the "system" side. |
I started CI meanwhile |
Test run: SUCCESSSummary: 6 of 6 test jobs passed |
|
||
//This is a handler function called from Fault handler to print the error information out. | ||
//This runs in fault context and uses special functions(defined in mbed_fault_handler.c) to print the information without using C-lib support. | ||
void mbed_fault_handler(uint32_t fault_type, const mbed_fault_context_t *mbed_fault_context_in); | ||
MBED_NORETURN void mbed_fault_handler(uint32_t fault_type, const mbed_fault_context_t *mbed_fault_context_in); |
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.
Can we make the fault handlers to be marked as no return only in release mode ?
Or at least provide a dead bx lr
only present when not building in release profile ?
Returning from precise faults has multiple times proven extremely useful.
This is nowadays rather cumbersome to achieve in mbed and I'd like to see it become easier rather than marking more functions as no return.
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.
This would take more than undoing this change - the assembler glue currently doesn't support mbed_fault_handler
returning, so this was just matching the C annotation to the assembler use. (Get a warning if we do try to return).
Are you thinking more of doing a BX lr
directly from the fault handler vector to unwind the stack to overcome backtrace unwinding problems in debuggers?
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.
Yes. I often break on HardFault_Handler
and try to find a bx lr
somewhere in the flash to then
set $pc = 0x_____
stepi
this is most on the time much easier to debug/understand the context of the fault than hopping for the debugger to sort out the content of a potentially corrupted memory.
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.
Another technique is to poke a "BX lr" onto the stack and execute it - there's a script around the place here people use to do that.
But this is working around a debugger deficiency. There's no fundamental reason in the world why a debugger cannot unwind the stack correctly from the fault vector. (If the BX lr works, the debugger can do the equivalent!) There are practical issues though, like it having to be in a GDB server, not the GDB core.
I spent a while getting this working a lot better in pyOCD's GDB server, at least, but it would need to be done separately for OpenOCD or any other GDB server. If the pyOCD RTOS awareness is on, then you should get a near-perfect display from the fault handler. pyocd/pyOCD#430 would make it basically perfect - showing you the faulting thread up-front without having to select it. I've another PR which would deal with the Thread/Handler stacks separately without RTOS awareness, but that's stale.
Anyway, this has no bearing on mbed_fault_handler
- by the time you've reached there, you're past the point where a mere BX lr
would take you back to the fault location. For your technique, stick the breakpoint on HardFault_Handler
.
@ithinuel Are you happy with this now ? |
CI started |
Test run: SUCCESSSummary: 6 of 6 test jobs passed |
NB: issues intriduced in ARMmbed#12824
Summary of changes
Fault handler assembly was very simplistic. Optimise for a 112 byte saving.
Also tidy up formatting, and make all 3 toolchain versions more consistent, for ease of diffing and transferring changes between them.
Also streamline access to crash capture region, avoiding use of pointers. Provides a small saving in fault handler even if crash capture is disabled.
Impact of changes
Migration actions required
Documentation
None
Pull request type
Test results
Reviewers