I have a 32 bit pointer which saves a password passed through a function and this password is used to compare to the saved password that I have.
uint32_t * password;
#define PASSWORDC 0x3f44d112
void pass_Init(uint32_t * pass) //pass is the address of 32 bit password being passed
{
password= pass; //no issues here
}
uint16_t PasswordEnter(void)
{
return (*password== PASSWORDC); //causes hardfault error due to alignment issues
}
void wipe(void){
*password= 0; //causes hardfault error due to alignment issues
}
As I have added in comments, that the assignment of value works, in fact while debugging, I see that in void pass_Init(uint32_t * pass)
the password gets the correct value to be assigned to it.
The issue happens if I do the comparison or any other operation which has *password = <something>
line to it. So it definitely seems to be an issue with alignment.
Please let me know how could I solve this.
I know I can use something like __attribute__((packed, aligned(4)))
, but I'm not sure how exactly to use it.
My code always calls the void pass_Init(uint32_t * pass) //pass is the address of 32 bit password being passed { password= pass; //no issues here } before doing any comparisons or assignments for that pointer. Even if I initialize my pointer as uint32_t * password = 0; I still get the hardfault error while comparing (although debugger shows *password has the correct value just before debugging) As far as I see, this seems like a problem where there is unaligned access to my uint32_t * pointer
CodePudding user response:
Dereferencing a null
or uninitialized pointer will invoke undefined behavior. There are several scenarios where this could happen in the code you have shown. Note that:
uint32_t * password;//creates an uninitialized pointer
At any point beyond the declaration of this pointer, the expression *password
is an int
, and more importantly indicates the pointer password
, is being dereferenced. So, depending on whether password is null (or initialized) at this point, it could be dereferencing a null
(or uninitialized) pointer. At that point, a seg-fault could occur.
uint16_t PasswordEnter(void)
{
return (*password== PASSWORDC); //causes hardfault error due to alignment issues
}
//exact same thing here:
void wipe(void){
*password= 0; //causes hardfault error due to alignment issues
}
CodePudding user response:
It appears that you have a problem with having one too many levels of indirection everywhere.
If the password is 32 bits and you want to store it in a global variable then store it in a global uint32_t, not a global uint32_t pointer.
Change the declaration of password from:
uint32_t * password;
to:
uint32_t password;
Now change the declaration of pass_Init:
void pass_Init(uint32_t pass)
{
password = pass;
}
And your other functions as follows:
bool PasswordEnter(void)
{
return (password == PASSWORDC);
}
void wipe(void)
{
password = 0;
}
Change the calling code (provided in comments) from:
pass_Init (&(UserPassword));
to
pass_Init (UserPassword);
Doing in this way results in simpler code at every line.