Hi
I'm writing my first ARM application. I have C++ code that works in Visual Studio on Windows and I am porting it to ARM using ARM Dev Studio. I want to target Cortex M6 but am currently targeting Cortex-A53 as that is suggested in the tutorial. My code builds ok and runs ok in the debugger up to a certain point, at which the debugger hangs when I try to step over the next line:
It seems to be a consequence of accessing the pointer rather than the cout. Earlier cout's work ok. I think the pointer is valid.
Please can you help me find out why this is happening? I don't know what to do next.
Thanks
David
Could it be something to do with 'cpuidle power down' ?
Hi DavidOn which line of C do you see the hang occurring? Is it on the cout? It isn't clear from the screen-shot.
The FVP model to which the Debugger is connected appears to be still running, so you should be able to press the Interrupt button (F9) to see where code execution has reached. Maybe an exception is occurring (due to e.g. a stack or heap overflow), but you have no exception handlers in place.
Try single stepping through the assembly code in the Disassembly view to see what instruction is causing the problem. To step instruction-by-instruction, press the "Step by instruction" button in the Debug Control view.
Where do you expect the cout output to appear - in the Debugger's console via semihosting, or via some hardware peripheral such as a UART?
Hope this helpsStephen
Hi Stephen
Thanks for your answer. The line on which the hang occurs is inconsistent actually. I'm expecting cout output in the Debugger's console via semihosting.
When I hit f9 it stops at:
Hi David,From the address (0x200), its does look like an exception is occurring, due to e.g. a stack or heap overflow (but you have no exception handlers in place), or maybe due to a semihosting call not being handled.Do you see any semihosting output in the Debugger's console? If not, are you compiling with GCC? The Debugger's automatic handling of semihosting is not enabled by default for GCC images.To check this, after connecting to the FVP model, do you see in the Commands view something like:Semihosting server socket created at port 8000Semihosting enabled automatically due to semihosting symbol detected in image
If not, then semihosting is not being enabled automatically in the Debugger.To enable this, you can either add "set semihosting enabled on" in the "Execute debugger commands" box in the debug launcher dialog, or add asm(" .global __auto_semihosting\n"); into your code.If semihosting is not the problem, then you'll need to identify which exception is occurring, and why. You can either single-step through through the assembly code in the Disassembly view to see what instruction is causing the problem (as I mentioned before), or use exception trapping.To trap the exception, in the Breakpoints view, click on "Manage Signals...". Initially, select to Stop and Print _all_ exceptions. You can refine this list (e.g. untick SYNC exceptions if you've ruled-out semihosting) later. You can also capture a history of instruction execution up to the exception, using "Trace". Open the .launch file, click on the "DTSL Options..." Edit button. In the Trace Buffer tab, select Model Trace. In the Core Trace tab, select the processor you want to trace. Click Debug to start a debug session. Open the Trace view from Window > Show View to see the instructions executed up to the exception, or to any breakpoint.
Hope this helps
Stephen
Hi Stephen,From the address (0x200), its does look like an exception is occurring, due to e.g. a stack or heap overflow (but you have no exception handlers in place), or maybe due to a semihosting call not being handled.Do you see any semihosting output in the Debugger's console? If not, are you compiling with GCC? The Debugger's automatic handling of semihosting is not enabled by default for GCC images.To check this, after connecting to the FVP model, do you see in the Commands view something like:Semihosting server socket created at port 8000Semihosting enabled automatically due to semihosting symbol detected in image
I see:Iris server started listening to port 7100terminal_0: Listening for serial connection on port 5000terminal_1: Listening for serial connection on port 5001terminal_2: Listening for serial connection on port 5002terminal_3: Listening for serial connection on port 5003Iris server is reported on port 7100
I added "set semihosting enabled on" in the "Execute debugger commands" box in the debug launcher dialog, but saw the same output.
Does this mean semihosting is not enabled?
I also tried:
asm(" .global __auto_semihosting\n");
int main(){
but got a build error:Error: L6218E: Undefined symbol __auto_semihosting (referred from hw_interface.o).
So instead I did:
void __auto_semihosting(void) __attribute__((alias("main")));
Is that ok? But I still see:Iris server started listening to port 7100terminal_0: Listening for serial connection on port 5000terminal_1: Listening for serial connection on port 5001terminal_2: Listening for serial connection on port 5002terminal_3: Listening for serial connection on port 5003Iris server is reported on port 7100
Best regards
Hi David,Look in the Commands view (not the Target console) for something like:Semihosting server socket created at port 8000Semihosting enabled automatically due to semihosting symbol detected in imageMy guess is the problem is due to stack or heap issues rather semihosting.
Suggest you try trapping the exception and tracing instruction execution up to it to investigate the cause of the exception. The exception reason will be shown in the Commands view.
If you are using GCC, please take a look at the other GCC-based projects that are provided in Arm DS, e.g. startup_Armv8-Ax1_GCC or startup_Cortex-A32_GCC.If you need more help with this, please raise a Support case using the Support > "Open a support case" above, so that our Support team can assist.Stephen
Thanks Stephen,
Before I go down the formal support route may I just mention that I see this in Commands:set semihosting enabled onERROR(TAB89-TAB180): ! Could not change semihosting enabled status! The semihosting breakpoint address has not been specified
Thanks David,I don't think the "set semihosting enabled on" is helping here, so I suggest you remove it. The FVP model should handle semihosting itself ("model semihosting") by deafult. This can be overriden by asking the Debugger the handle semihosting instead ("debugger semihosting") with "set semihosting enabled on" command, but this shouldn't be needed in this case.Suggest you try trapping the exception and tracing instruction execution up to it instead.Hope this helps to identify the offending instruction.Stephen
Hi Stephen,
I realise I am ignoring your suggestion to use formal support, but I wonder if you could bear with me a little longer please.
I selected Stop and Print All exceptions. The code now breaks and issues this in the Commands tab:waitnextExecution stopped in EL3h mode at EL3:0x000000008000A40CEL3:0x000000008000A40C 168,38 unsigned sectionId = p_sectionInfo->sectionId_rb_symInc_startPrbc_numPrbc_struct.sectionId; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^waitnextSynchronous exception within EL3 with EL3 Stack PointerExecution stopped in EL3h mode at EL3:0x0000000000000200In processDlUplaneList (no debug info)EL3:0x0000000000000200 DCI 0xe7ff0010 ; ? Undefineddelete 2Breakpoint 2 deleted
Any thoughts please?
Hi David,To see which instruction causes the exception, you should either single-step at instruction level and watch the Disassembly view on each step, or run (not step) to the exception trap and then look at the instructions in the Trace view.From the output you gave, it looks like the instruction at/near 0x8000A40C is the culprit.In the screenshot below, using the startup_Armv8-Ax1_GCC (where I've deliberately changed SP to an invalid value), the Trace is showing that the STP instruction at 0x80003170 caused the exception.Stephen
I mentioned above that the exception occurs when accessing a member of a structure:Execution stopped in EL3h mode at EL3:0x000000008000A40CEL3:0x000000008000A40C 168,38 unsigned sectionId = p_sectionInfo->sectionId_rb_symInc_startPrbc_numPrbc_struct.sectionId; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The interesting thing is that sectionId is a bit field in a union:
Are you aware of any restrictions of the armclang compiler that might prevent access to such bitfields?
Hi DavidI suspect that the exception is being caused by an unaligned access to memory. To confirm this, you'll need to identify the exact instruction that triggers the exception (by trapping the exception and tracing instruction execution up to it, as described earlier), then place a breakpoint on that instruction in the Disassembly view, and run again. When the breakpoint hits, open the Registers view to see the exact address that the instruction is trying to access. Is it an unaligned (i.e. non-32-bit) address?If so, you can either configure the core in the FVP model to allow unaligned accesses (with the A bit in the SCTLR), or prevent the compiler from generating code that uses unaligned accesses - seehttps://developer.arm.com/documentation/101754/0616/armclang-Reference/armclang-Command-line-Options/-munaligned-access---mno-unaligned-accessThere may be a performance and/or code size impact, depending on your choice.See also "packed" structures athttps://developer.arm.com/documentation/101754/0616/armclang-Reference/Compiler-specific-Function--Variable--and-Type-Attributes/--attribute----packed---type-attributeandhttps://developer.arm.com/documentation/100748/0616/Writing-Optimized-Code/Packing-data-structuresHope this helpsStephen
Thanks very much for your help with this thread. I will accept your answer now so that we can close it.