This is a piece of code, which did work, but suddenly started throwing segfaults after I had changed a library function call in a different piece of code. Here is what gdb says:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x75bae3d0 (LWP 756)]
0x00000000 in ?? ()
Here are the relevant chunks of code, which cause the issue:
void relay::IgnitionISR (int handler, unsigned int pin, unsigned int level, uint32_t tick)
{
cout << "¤¤ " << relay::ignition_on_off_event_handler << " ¤¤" << endl;
if (level == 1) {
keypad::SetLock (keypad::ON_OFF);
relay::ignition_on_off_event_handler (true, tick);
}
else {
keypad::SetLock (keypad::LOCKED);
relay::ignition_on_off_event_handler (false, tick);
}
}
When this method is called by an external trigger (see below), I always get this output:
¤¤ 0 ¤¤
The event handler is declared in the header file like this:
typedef void (*ignition_event_handler) (bool, uint32_t);
private:
static ignition_event_handler ignition_on_off_event_handler;
static void IgnitionISR (int handler, unsigned int pin, unsigned int level, uint32_t tick);
The function pointer is set in this method:
int relay::Initialize (int pi_handler, ignition_event_handler ign_handler)
{
int result = 0;
bool is_ok = true;
relay::pigpiod_handler = pi_handler;
relay::ignition_on_off_event_handler = ign_handler;
result = callback (relay::pigpiod_handler, IGNITION_PIN, EITHER_EDGE, (CBFunc_t) relay::IgnitionISR);
// This method from pigpiod_if2.h essentially makes the ISR being called once the state of the pin given changes.
if (result == pigif_bad_malloc || result == pigif_duplicate_callback || result == pigif_bad_callback) {
cout << "ERROR on pin " << IGNITION_PIN << "! Code: " << result << ".";
is_ok = false;
}
cout << "¤¤ " << relay::ignition_on_off_event_handler << " ¤¤" << endl;
return result;
}
In the past (when I used to address pigpio directly), I was using this method from pigpio.h
instead of callback ()
, and the event handler worked well:
gpioSetAlertFunc (IGNITION_PIN, IgnitionISR);
This is how the initializing method is called from the main ()
procedure in main.c
:
ret = relay::Initialize (pigpiod_handler, OnIgnitionSwitched);
And this is how the handler function itself (whose pointer is used) is defined in main.c
:
void OnIgnitionSwitched (bool is_on, uint32_t tick)
{…}
From the initializing method, I always get this output:
¤¤ 1 ¤¤
And here comes my problem: How can the function pointer value suddenly become 0 when triggering the ISR, as the corresponding variable is private, and no other piece of code from within the class writes to it? Thank you for any useful hints!
User contributions licensed under CC BY-SA 3.0