Skip to content

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

Merged
merged 3 commits into from
Jun 18, 2020
Merged

Optimise fault handler assembly #12824

merged 3 commits into from
Jun 18, 2020

Conversation

kjbracey
Copy link
Contributor

@kjbracey kjbracey commented Apr 17, 2020

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

[X] Patch update (Bug fix / Target update / Docs update / Test update / Refactor)
[] Feature update (New feature / Functionality change / New API)
[] Major update (Breaking change E.g. Return code change / API behaviour change)

Test results

[] No Tests required for this change (E.g docs only update)
[X] Covered by existing mbed-os tests (Greentea or Unittest)
[] Tests / results supplied as part of this PR

Reviewers


@ciarmcom ciarmcom requested review from a team April 17, 2020 11:00
@ciarmcom
Copy link
Member

@kjbracey-arm, thank you for your changes.
@ARMmbed/mbed-os-core @ARMmbed/mbed-os-maintainers please review.

@kjbracey kjbracey force-pushed the faultasm branch 3 times, most recently from cad2be9 to dce3712 Compare April 17, 2020 11:45
LDR R1,[R3]
BL mbed_fault_handler
MOVS R1,R7
SUBS R1,#21*4
Copy link
Contributor

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

Copy link
Contributor Author

@kjbracey kjbracey Apr 17, 2020

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
Copy link
Contributor

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?

Copy link
Contributor Author

@kjbracey kjbracey Apr 17, 2020

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.

@kjbracey
Copy link
Contributor Author

Corrected addressing of stack frame if it's on the Main Stack - needed ADD R6,SP,#16 not MOV R6,SP because we've just pushed R4-R7.

@0xc0170
Copy link
Contributor

0xc0170 commented Apr 20, 2020

CI restarted

@0xc0170
Copy link
Contributor

0xc0170 commented Apr 20, 2020

early note: GCC failed

I found one error at least: [Fatal Error] mbed_crash_data_offsets.h@21,10: platform/TARGET_CORTEX_M/mbed_fault_handler.h: No such file or directory [ERROR] In file included from ./mbed-os/platform/source/TARGET_CORTEX_M/mbed_fault_handler.c:28: ./mbed-os/platform/source/mbed_crash_data_offsets.h:21:10: fatal error: platform/TARGET_CORTEX_M/mbed_fault_handler.h: No such file or directory 21 | #include "platform/TARGET_CORTEX_M/mbed_fault_handler.h" | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ compilation terminated.

@mbed-ci
Copy link

mbed-ci commented Apr 20, 2020

Test run: FAILED

Summary: 2 of 3 test jobs failed
Build number : 1
Build artifacts

Failed test jobs:

  • jenkins-ci/mbed-os-ci_build-GCC_ARM
  • jenkins-ci/mbed-os-ci_build-ARM

@kjbracey
Copy link
Contributor Author

My bad - botched rebase of work originally done on a fork.

@kjbracey
Copy link
Contributor Author

kjbracey commented Apr 20, 2020

Fixed. mbed_fault_handler.h moved into platform/internal from platform/source as mbed_crash_data_offsets.h now needs it.

(Although - shouldn't it be public? Is mbed_get_reboot_fault_context not intended to be a public function?)

@0xc0170
Copy link
Contributor

0xc0170 commented Apr 21, 2020

mbed_get_reboot_fault_context - I would say it should be public, same applied in the design doc:

The below API can be called by application to retrieve the fault context captured in the Crash-Report RAM. The error context is copied into the location pointed by fault_context.

@0xc0170
Copy link
Contributor

0xc0170 commented Apr 21, 2020

Travis is failing still.

@kjbracey kjbracey force-pushed the faultasm branch 2 times, most recently from 3ea954f to 12d8915 Compare April 22, 2020 10:11
Tidy up formatting, and make all 3 toolchain versions more consistent,
for ease of diffing and transferring changes between them.
@kjbracey
Copy link
Contributor Author

kjbracey commented Apr 28, 2020

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 mbed_fault_handler, if it was enabled for Cortex-A. But the existing code wouldn't know how to print it - would need some ifdefs.

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.

@0xc0170
Copy link
Contributor

0xc0170 commented May 8, 2020

I started CI meanwhile

@mbed-ci
Copy link

mbed-ci commented May 8, 2020

Test run: SUCCESS

Summary: 6 of 6 test jobs passed
Build number : 3
Build artifacts


//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);
Copy link
Member

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.

Copy link
Contributor Author

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?

Copy link
Member

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.

Copy link
Contributor Author

@kjbracey kjbracey May 29, 2020

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.

@adbridge
Copy link
Contributor

@ithinuel Are you happy with this now ?

@adbridge adbridge added the release-type: patch Indentifies a PR as containing just a patch label Jun 11, 2020
@0xc0170
Copy link
Contributor

0xc0170 commented Jun 17, 2020

CI started

@mbed-ci
Copy link

mbed-ci commented Jun 17, 2020

Test run: SUCCESS

Summary: 6 of 6 test jobs passed
Build number : 4
Build artifacts

@0xc0170 0xc0170 merged commit 62c2431 into ARMmbed:master Jun 18, 2020
@mergify mergify bot removed the ready for merge label Jun 18, 2020
@adbridge adbridge removed release-type: patch Indentifies a PR as containing just a patch Release-pending labels Jun 30, 2020
jeromecoutant added a commit to jeromecoutant/mbed that referenced this pull request Jul 8, 2020
NB: issues intriduced in ARMmbed#12824
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants