Hi guys,
I'm experience some crazy behavior of code which is beyond my understandings. Problem is that when calling function from function and passing argument, that argument gets scrambled or not passed at all (don't know which option is going on).
Crazy about this is, that when I'm trying to change the code, sometimes it works as expected but then after changing more code, it stops working. And of course, this is really unpredictable and not depends on variable manipulation in suspect.
Here is the typedef and code snippet:
typedef struct { uint8_t Button; uint8_t ButtonState; uint8_t Index; } FncCallPayloadButton_t; typedef struct { enum CS_SectionID_e TargetSection; uint8_t ActionType; void* Payload; } FncCallPayload_t; typedef FncCallPayload_t* pFncCallPayload; typedef uint8_t ( *pFncCS ) ( pFncCallPayload FncCallPayload );
void CS_Dummy( pFncCallPayload FncCallPayload ) { CDC_SendString_P( PSTR("CS_Dummy " ) ); CDC_SendNumber( ( (FncCallPayloadButton_t*) FncCallPayload->Payload )->Index ); PrintMemory( (uint8_t*) FncCallPayload->Payload, 16, MEMORY_RAM | MEMORY_PRINT_USEPRINTABLE ); } static uint8_t CS_Load( pFncCallPayload FncCallPayload ) { CDC_SendString_P( PSTR("CS_Load" ) ); CDC_SendNewLine(); CDC_SendNumber( ( (FncCallPayloadButton_t*) FncCallPayload->Payload )->Index ); PrintMemory( (uint8_t*) FncCallPayload->Payload, 16, MEMORY_RAM | MEMORY_PRINT_USEPRINTABLE ); FncCallPayload->TargetSection = CS_SEC_BROADCAST; SetReturnSet( FncCallPayload ); CS_Set( CS_SET_LOAD, FncCallPayload ); } void CS_CallButtonFunction( pFncCallPayload FncCallPayload ) { CDC_SendString_P( PSTR("CS_CallButtonFunction" ) ); CDC_SendNewLine(); PrintMemory( (uint8_t*) FncCallPayload->Payload, 16, MEMORY_RAM | MEMORY_PRINT_USEPRINTABLE ); CS_Dummy( FncCallPayload ); FncCallPayloadButton_t* FncCallPayloadButton = (FncCallPayloadButton_t*) FncCallPayload->Payload; uint8_t BtnFncCallIndex; switch ( FncCallPayloadButton->ButtonState ) { case BTN_ACTION_TYPE_1CLK: BtnFncCallIndex = 0; break; case BTN_ACTION_TYPE_2CLK: BtnFncCallIndex = 1; break; case BTN_ACTION_TYPE_3CLK: BtnFncCallIndex = 2; break; case BTN_ACTION_TYPE_HOLD: BtnFncCallIndex = 3; break; } BtnActions_t* pBtnAction = (BtnActions_t*) pgm_read_word ( &CS_Sections[ FncCallPayload->TargetSection ].BtnActions ); if ( pBtnAction == NULL ) return; enum CS_SectionButtonsRef_e BtnActionRef = (enum CS_SectionButtonsRef_e) pgm_read_byte ( &CS_Sections[ FncCallPayload->TargetSection ].BtnActionsReferenceType ); if ( BtnActionRef == CS_SEC_BUTTON_ACTION_DISTINCT ) pBtnAction += FncCallPayloadButton->Index; pFncCS FncCall = (pFncCS) pgm_read_word ( (pFncCS*) pBtnAction + BtnFncCallIndex ); PrintMemory( (uint8_t*) FncCallPayload->Payload, 16, MEMORY_RAM | MEMORY_PRINT_USEPRINTABLE ); if ( FncCall != NULL ) { CS_Dummy( FncCallPayload ); FncCall( FncCallPayload ); } }
object payload is generated like this:
void ControlSurfaceProcessButton( uint8_t Button, uint8_t EventType ) { FncCallPayload_t FncCallPayload; FncCallPayloadButton_t FncCallPayloadButton; FncCallPayloadButton.Button = Button; FncCallPayloadButton.ButtonState= EventType; FncCallPayload.TargetSection = CS_SEC_FINDCONTROLTARGET; FncCallPayload.ActionType = CS_ACTION_BUTTON; FncCallPayload.Payload = &FncCallPayloadButton; CS_Action( &FncCallPayload ); }
and after call to CS_ProcessButoonFunction output is like this (don't mind garbled characters, these are not results from memory corruption but rather my lightweight int2str which takes int16 only):
CS_CallButtonFunction 0AD3: 0015 - 0E 02 02 0 * 11 12 EB 01 EB 01 CS_Dummy 000AB -▒55: 0015 - F0 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 0AD3: 0015 - 0E 02 02 0 * 11 12 EB 01 EB 01 CS_Dummy 000AB -▒55: 0015 - F0 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A CS_Load 000AB -▒55: 0015 - F0 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A
What is crazy is that after entering CS_CallButtonFunction data on argument are valid, but are not valid in functions called from here, but are still valid even after some functions has been called (which could indicate that stack corruption is not goinf on).
Currently I'm compiling with flto option, but this is also happening without flto option compilation. I've run out of ideas what could be the cause of this.
Does anybody have an idea what's going on?
Thanks a lot.
T.