From 4a98e9c9847e391d57095bcb1ccea52b676fc0dd Mon Sep 17 00:00:00 2001 From: Che-yu Wu Date: Tue, 5 Sep 2017 13:58:35 +0800 Subject: extra/stack_analyzer: Configurable exception frame size. Make the size of extra stack needed by exceptions configurable. It can be set in the annotation file. BUG=chromium:648840 BRANCH=none TEST=extra/stack_analyzer/stack_analyzer_unittest.py make BOARD=elm SECTION=RW \ ANNOTATION=./extra/stack_analyzer/example_annotation.yaml \ analyzestack Change-Id: Idf2a59650dd20257a0291f89d788c0c83b91a7c9 Signed-off-by: Che-yu Wu Reviewed-on: https://chromium-review.googlesource.com/649454 Reviewed-by: Nicolas Boichat --- extra/stack_analyzer/README.md | 1 + extra/stack_analyzer/example_annotation.yaml | 3 +++ extra/stack_analyzer/stack_analyzer.py | 12 +++++++----- extra/stack_analyzer/stack_analyzer_unittest.py | 9 ++++++--- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/extra/stack_analyzer/README.md b/extra/stack_analyzer/README.md index 0933959249..b809ccc5a2 100644 --- a/extra/stack_analyzer/README.md +++ b/extra/stack_analyzer/README.md @@ -41,6 +41,7 @@ The callsites to the next function will be shown like below, - handle_request[common/usb_pd_protocol.c:1191] - handle_data_request[common/usb_pd_protocol.c:798] -> pd_task[common/usb_pd_protocol.c:2672] 1008c222 +-> [annotation] ``` This means one callsite to the next function is at `usb_pd_protocol.c:798`, but it is inlined to the current function and you can follow the trace: diff --git a/extra/stack_analyzer/example_annotation.yaml b/extra/stack_analyzer/example_annotation.yaml index 92dff8922f..084fabc2d1 100644 --- a/extra/stack_analyzer/example_annotation.yaml +++ b/extra/stack_analyzer/example_annotation.yaml @@ -1,3 +1,6 @@ +# Size of extra stack frame needed by exception context switch. +exception_frame_size: 64 + # Add some missing calls. add: # console_task also calls command_display_accel_info and command_accel_init. diff --git a/extra/stack_analyzer/stack_analyzer.py b/extra/stack_analyzer/stack_analyzer.py index af58ef7ef0..f08470bafc 100755 --- a/extra/stack_analyzer/stack_analyzer.py +++ b/extra/stack_analyzer/stack_analyzer.py @@ -26,9 +26,9 @@ import yaml SECTION_RO = 'RO' SECTION_RW = 'RW' -# TODO(cheyuw): This should depend on the CPU and build options. -# The size of extra stack frame needed by interrupts. (on cortex-m with FPU) -INTERRUPT_EXTRA_STACK_FRAME = 224 +# Default size of extra stack frame needed by exception context switch. +# This value is for cortex-m with FPU enabled. +DEFAULT_EXCEPTION_FRAME_SIZE = 224 class StackAnalyzerError(Exception): @@ -1259,13 +1259,15 @@ class StackAnalyzer(object): cycle_functions = self.AnalyzeCallGraph(function_map, remove_list) # Print the results of task-aware stack analysis. + extra_stack_frame = self.annotation.get('exception_frame_size', + DEFAULT_EXCEPTION_FRAME_SIZE) for task in self.tasklist: routine_func = function_map[task.routine_address] print('Task: {}, Max size: {} ({} + {}), Allocated size: {}'.format( task.name, - routine_func.stack_max_usage + INTERRUPT_EXTRA_STACK_FRAME, + routine_func.stack_max_usage + extra_stack_frame, routine_func.stack_max_usage, - INTERRUPT_EXTRA_STACK_FRAME, + extra_stack_frame, task.stack_max_size)) print('Call Trace:') diff --git a/extra/stack_analyzer/stack_analyzer_unittest.py b/extra/stack_analyzer/stack_analyzer_unittest.py index a3bd80a186..cac4383906 100755 --- a/extra/stack_analyzer/stack_analyzer_unittest.py +++ b/extra/stack_analyzer/stack_analyzer_unittest.py @@ -590,18 +590,21 @@ class StackAnalyzerTest(unittest.TestCase): ) addrtoline_mock.return_value = [('??', '??', 0)] - self.analyzer.annotation = {'remove': [['fake_func']]} + self.analyzer.annotation = { + 'exception_frame_size': 64, + 'remove': [['fake_func']], + } with mock.patch('__builtin__.print') as print_mock: checkoutput_mock.return_value = disasm_text self.analyzer.Analyze() print_mock.assert_has_calls([ mock.call( - 'Task: HOOKS, Max size: 232 (8 + 224), Allocated size: 2048'), + 'Task: HOOKS, Max size: 72 (8 + 64), Allocated size: 2048'), mock.call('Call Trace:'), mock.call(' hook_task (8) [??:0] 1000'), mock.call( - 'Task: CONSOLE, Max size: 240 (16 + 224), Allocated size: 460'), + 'Task: CONSOLE, Max size: 80 (16 + 64), Allocated size: 460'), mock.call('Call Trace:'), mock.call(' console_task (8) [??:0] 2000'), mock.call(' -> ??[??:0] 2002'), -- cgit v1.2.1