cancel
Showing results for 
Search instead for 
Did you mean: 

Why are calls to strcat() not actually calling strcat()? (and why do I sometimes get a Hard Fault)

MButsch
Associate III

I am using STM32CubeIDE v1.6.1 and am seeing some strangeness.

When I call strcat(), I get a hardfault if the end of the string (where the nul is) being catted to is at an odd address?

Here is code from the .list file:

		  char s1[20];
		  strcpy(s1, "--");
 800ab50:	f107 030c 	add.w	r3, r7, #12
 800ab54:	4a65      	ldr	r2, [pc, #404]	; (800acec <sd_cmdproc_process_packet+0x374>)
 800ab56:	6812      	ldr	r2, [r2, #0]
 800ab58:	4611      	mov	r1, r2
 800ab5a:	8019      	strh	r1, [r3, #0]
 800ab5c:	3302      	adds	r3, #2
 800ab5e:	0c12      	lsrs	r2, r2, #16
 800ab60:	701a      	strb	r2, [r3, #0]
		  strcat(s1, "1");
 800ab62:	f107 030c 	add.w	r3, r7, #12
 800ab66:	4618      	mov	r0, r3
 800ab68:	f7f5 fbc4 	bl	80002f4 <strlen>
 800ab6c:	4603      	mov	r3, r0
 800ab6e:	461a      	mov	r2, r3
 800ab70:	f107 030c 	add.w	r3, r7, #12
 800ab74:	4413      	add	r3, r2
 800ab76:	495e      	ldr	r1, [pc, #376]	; (800acf0 <sd_cmdproc_process_packet+0x378>)
 800ab78:	461a      	mov	r2, r3
 800ab7a:	460b      	mov	r3, r1
 800ab7c:	881b      	ldrh	r3, [r3, #0]
 800ab7e:	8013      	strh	r3, [r2, #0]
		  strcat(s1, "2");
 800ab80:	f107 030c 	add.w	r3, r7, #12
 800ab84:	4618      	mov	r0, r3
 800ab86:	f7f5 fbb5 	bl	80002f4 <strlen>
 800ab8a:	4603      	mov	r3, r0
 800ab8c:	461a      	mov	r2, r3
 800ab8e:	f107 030c 	add.w	r3, r7, #12
 800ab92:	4413      	add	r3, r2
 800ab94:	4957      	ldr	r1, [pc, #348]	; (800acf4 <sd_cmdproc_process_packet+0x37c>)
 800ab96:	461a      	mov	r2, r3
 800ab98:	460b      	mov	r3, r1
 800ab9a:	881b      	ldrh	r3, [r3, #0]
 800ab9c:	8013      	strh	r3, [r2, #0]
 800ab9e:	e1c4      	b.n	800af2a <sd_cmdproc_process_packet+0x5b2>
  }

the strcat of "1" works, but the strcat of "2" hard faults. I suspect it isalignment error with the "strh".

It is also curious that the calls to strcat() (and strcpy()) do not call the actual functions.

I appologize if I have missed something obvious.

Thanks,

mark

13 REPLIES 13

Are you using a Cortex-M0(+) processor?

Sometimes these calls are folded inline or use intrinsics.

Most Cortex can handle unaligned 16 or 32-bit access, all will fail with LDRD/STRD

Optimization

Correct Core Selection for compiler/libraries

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
MButsch
Associate III

Guess I should have included that information at the start...

This project is using a Cortex-M7 (STM32F769NIHx) on the STM32F769I-DISCO board.

Here are the gcc options shown in Properties->C/C++ Build->Settings->MCU GCC Compiler->All Options:

-mcpu=cortex-m7 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32F769xx -c -I../Core/Inc -I../Drivers/STM32F7xx_HAL_Driver/Inc -I../Drivers/STM32F7xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM7/r0p1 -I../Drivers/CMSIS/Device/ST/STM32F7xx/Include -I../Drivers/CMSIS/Include -I"C:\Users\mbutsch\STM32CubeIDE\workspace_1.6.1\F769-FlashFS\synlib\Inc" -I"C:\Users\mbutsch\STM32CubeIDE\workspace_1.6.1\syntalk\c" -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage --specs=nano.specs -mfpu=fpv5-d16 -mfloat-abi=hard -mthumb

> the strcat of "1" works, but the strcat of "2" hard faults.

How do you know?

> FreeRTOS

What about stack overflow?

JW

I've posted a couple of Hard Fault Handlers that output actionable data. Interested in a full register complement, and fault location.

I'm not sure the STRH will fail inherently due to an odd address, make sure the strlen() hasn't failed due to missing NUL

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

when I singlestep (instruction mode) through the code, inspecting the variable s1....

strcpy(s1, "--"); yields s1 == "--"

strcat(s1, "1"); yields s1 == "--1"

strcat(s1, "2"); yields hard fault when it executes 'strh r3, [r2, #0]'

here are registers after hard fault

pulFaultStackAddress	uint32_t *	0x20002390 <ucHeap+5360>	
r0	volatile uint32_t	0x3 (Hex)	
r1	volatile uint32_t	0x801d45c (Hex)	
r2	volatile uint32_t	0x200023cf (Hex)	
r3	volatile uint32_t	0x32 (Hex)	
r12	volatile uint32_t	0xa (Hex)	
lr	volatile uint32_t	0x800adb3 (Hex)	
pc	volatile uint32_t	0x800adc4 (Hex)	
psr	volatile uint32_t	0x21000000 (Hex)	

where have you posted Hard Fault Handlers? They may be better than what I have in place currently.

Giving the depressingly awful search afforded by SalesForce (a multi-billion dollar outfit..)

https://github.com/cturvey/RandomNinjaChef/blob/main/KeilHardFault.c

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

> pc volatile uint32_t 0x800adc4 (Hex)

That's not in the region you provided the disasm for above.

0x200023cf is in DTCM. Cortex-M7 should allow unaligned accesses there, unless you've set that area as Device or Strongly Ordered in MPU, or you've disabled unaligned accesses generally by setting SCB_CCR.UNALIGN_TRP.

JW