2020-01-15 05:38 PM
I use "sprintf (string,"comment"); everywhere
now for some reason, I am getting a hardfault. in an innocuous print.
length += sprintf(String + length, "Received Packet from ");
length is only 15.
String is declared as
char String[256];
I guess it is using malloc,
How do we check the allocations are being cleared ?
I never use malloc anywhere, so its not me...
2020-01-15 06:17 PM
Added to heap and stack but did not fix the problem:
in STM32H743ZI_flash.lds
.heap (NOLOAD) :
{
. = ALIGN(4);
PROVIDE(__heap_start__ = .);
KEEP(*(.heap))
. = ALIGN(4);
. = . + 0x2000;
PROVIDE(__heap_end__ = .);
} > SRAM
.reserved_for_stack (NOLOAD) :
{
. = ALIGN(4);
PROVIDE(__reserved_for_stack_start__ = .);
KEEP(*(.reserved_for_stack))
. = ALIGN(4);
. = . + 0x2000;
PROVIDE(__reserved_for_stack_end__ = .);
} > SRAM
2020-01-15 06:29 PM
Does length get initialized or corrupt?
Not sure where the allocators is beyond _sbrk, but in other systems you could try walking the heap list.
I guess look specifically at where it is faulting, and via a listing. See what it is actually using, and perhaps if you can unwind the allocator code and call-tree that's getting you here.
With strings always make sure everything has a NUL termination, especially if there are some memcpy() or "%s" being used.
2020-01-15 06:52 PM
Thanks for the good advice @Community member however, very difficult to do any debug.
length is definately only 0x15 when the allocated String locally is 256 bytes.
now to unwind the allocator code, ?
"specifically at where it is faulting, and via a listing"
it is "FRAME OUT OF BOUNDS" from Visual Studio so I cant see anything.
strangely, all other lines of sprintf around this one seem to operate ok, only this one is a problem. ?
maybe
a code boundary ?
stack nesting ?
removed a 12 nest if/else without fixing it.
how can I walk the heap list?
sprintf always inserts the null.. and using " Sting+length" will override it anyhow.
dont use the %s operator at all. nor string copy or memcopy.
( i use the Null to copy strings, ie while(*ptr) // is not null )
looking to generate the map file now.
2020-01-15 07:28 PM
If it corrupts the stack the processor can vector off to locations it has no code to show you. You've seen my fault routines, these allow for an inside-the-box view of the failure if the debugger is unhelpful.
Typically the way heap work is you have a linked list of allocated and unallocated space, it should fold contiguous unallocated space during free()
To get to the list you typically subtract space for a structure in front of the pointer returned by malloc(). ie foo = malloc(100); the link list structure can be found at foo-32 (for example). Look at how free() is implemented, and what it does with the pointer you pass in. There is likely a back/forward pointer and a size.
Not saying it is the heap, the stack tends to be the biggest issue. In ST/GCC they usually have the heap/stack together allowing one to crash into the other.
2020-01-15 07:30 PM
the map file: no boundaries here
faulty function is inside: ProcessReceivedFrame { }
.text.ProcessReceivedFrame
0x0800ba28 0x188 VisualGDB/Debug/nCan.o
0x0800ba28 ProcessReceivedFrame
.text.HAL_FDCAN_RxBufferNewMessageCallback
0x0800bbb0 0x1c VisualGDB/Debug/nCan.o
0x0800bbb0 HAL_FDCAN_RxBufferNewMessageCallback
sprintf in map file:
thumb/fpu/cortex_m7\libc_nano.a(lib_a-sprintf.o)
0x08001d70 _sprintf_r
0x08001d70 _siprintf_r
0x08001dac siprintf
0x08001dac sprintf
*fill* 0x08001df0 0x10
the heap in Map file, and surrounds
0x2400fcd4 retSD
0x2400fcd8 SDPath
0x2400fcdc SDFile
0x2400ff0c SDFatFS
COMMON 0x24010140 0x4 c:/sysgcc/arm-eabi/bin/../lib/gcc/arm-eabi/7.2.0/../../../../arm-eabi/lib/thumb/fpu/cortex_m7\libc_nano.a(lib_a-reent.o)
0x24010140 errno
0x24010144 . = ALIGN (0x4)
0x24010144 _ebss = .
0x24010144 PROVIDE (__bss_end__, _ebss)
0x24010144 PROVIDE (end, .)
.heap 0x24010144 0x2000 load address 0x080337d8
0x24010144 . = ALIGN (0x4)
[!provide] PROVIDE (__heap_start__, .)
*(.heap)
0x24010144 . = ALIGN (0x4)
0x24012144 . = (. + 0x2000)
*fill* 0x24010144 0x2000
[!provide] PROVIDE (__heap_end__, .)
.reserved_for_stack
0x24012144 0x2000 load address 0x080337d8
0x24012144 . = ALIGN (0x4)
[!provide] PROVIDE (__reserved_for_stack_start__, .)
*(.reserved_for_stack)
0x24012144 . = ALIGN (0x4)
0x24014144 . = (. + 0x2000)
*fill* 0x24012144 0x2000
[!provide] PROVIDE (__reserved_for_stack_end__, .)
.image_storage 0x30000000 0x48000
0x30000000 . = ALIGN (0x4)
[!provide] PROVIDE (__Image_Store__, .)
.image_storage
0x30000000 0x48000 VisualGDB/Debug/bios.o
0x30000000 BigBuffer
.aligned_storage
0x38000000 0x7800
0x38000000 . = ALIGN (0x4)
[!provide] PROVIDE (__Aligned_Store__, .)
.aligned_storage
0x38000000 0x7800 VisualGDB/Debug/bios.o
0x38000000 Usart1RxDMABuffer
0x38000400 Usart1TxDMABuffer
0x38002400 Usart2RxDMABuffer
0x38002800 Usart2TxDMABuffer
0x38003800 string
0x38004800 flashBuffer
0x38005800 RamDirectory
OUTPUT(VisualGDB/Debug/H743_LCD_2 elf32-littlearm)
2020-01-15 07:40 PM
I have set the Heap/Stack to 8Kbytes, wouldn't think that is an issue after doubling it and now it still fails in the same sprintf
regarding your hardfault handler:
this is declared
/* These types MUST be 32-bit */
typedef long LONG;
typedef unsigned long DWORD;
/* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */
typedef unsigned long long QWORD;
looking inside your hardfault handler: but it just fails...
void hard_fault_handler_c(unsigned int * hardfault_args, unsigned int r4, unsigned int r5, unsigned int r6)
{
DWORD reg1 = hardfault_args[1]; <- crashes here, single step fails to here.
DWORD reg2 = hardfault_args[2];
DWORD reg3 = hardfault_args[0];
DWORD reg4 = r4;
I have the dataCache off, will try the instructionCache off
2020-01-15 07:44 PM
still fails with ICache OFF,
here is the errant code:
ProcessReceivedFrame(dataChannel, FifoMsgLength); // check if this packet contains a valid address
{
if (showRxCanFrames) {
char String[256];
int length = 0;
length += sprintf(String + length, "Received Packet from "); // this line works
if (have_LCD)
length += sprintf(String + length, "LCD unit ");
//else
if(have_Facex)
length += sprintf(String + length, "Facex unit ");
//else
if(have_FA4)
length += sprintf(String + length, "FA4 unit ");
//else
if(have_FA1)
length += sprintf(String + length, "FA1 unit ");
//else
if(have_FA2)
length += sprintf(String + length, "FA2 unit ");
//else
if(have_AimTA)
length += sprintf(String + length, "AIM_TA unit ");
//else
if(have_AimTC)
length += sprintf(String + length, "AIM_TC unit "); // <- fails here
// else
if(have_AimHTC)
2020-01-15 07:50 PM
Can you change behaviour with a "static char String[256]" ?
Doesn't look bad..
Does length look problematic? Clearly don't have 256 chars in preceding sprintf
2020-01-15 07:58 PM