Если вы готовы написать непереносимый код и проверить его перед его развертыванием, и если процессор его поддерживает, возможно, существует решение.
Когда вызывается обработчик прерываний, адрес возврата должен где-то храниться. Если это местоположение, к которому может обращаться ваш код - например, фиксированное смещение вниз по стеку - тогда вы можете сравнить этот адрес с диапазоном, занятым вашей функцией, чтобы определить, выполняется ли 'foo_called'. Вы можете получить адрес функции, сохранив фиктивный адрес, скомпилировав, проанализировав файл карты, затем обновив адрес и перекомпилировав.
Затем, если ваш процессор поддерживает его, вы можете заменить адрес возврата на адрес последней инструкции (инструкций) foo_called. (убедитесь, что вы включили очистку стека и зарегистрировали код восстановления.). Затем выйдите из прерывания как обычно, и логика обработки прерываний вернет код до конца вашей прерванной функции.
Если адрес возврата хранится не в стеке, а в незаписываемом регистре, вы все равно сможете принудительно завершить свою функцию - если исполняемый код находится в записываемой памяти. Просто сохраните инструкцию по адресу возврата прерывателя, затем перезапишите ее инструкцией перехода, которая переходит к концу функции. В коде вызывающего абонента добавьте детектор, который восстановил перезаписанную инструкцию.