Fix the bug introduced by the PR #1406.#1413
Merged
bcoconni merged 3 commits intoJSBSim-Team:masterfrom Apr 3, 2026
Merged
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1413 +/- ##
=======================================
Coverage 25.12% 25.12%
=======================================
Files 169 169
Lines 18721 18721
=======================================
Hits 4703 4703
Misses 14018 14018 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Contributor
|
@bcoconni great contribution, looks good to me. |
Contributor
|
Looks good. |
Member
Author
|
OK. Thanks. PR merged. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Following the merge of PR #1406, the test
TestFunctions.pyfails with a SEGFAULT.TLDR: The failure is due to trying to run Python code while a Python exception has been raised. This PR catches the Python exception prior to running code in the
FGLoggerclass then rethrows.The failure sequence
The test
test_table_exceptioninTestFunctions.pysets the conditions forFGFDMExec.load_modelto throw an exception then checks that the exception has indeed been thrown:jsbsim/tests/TestFunctions.py
Lines 330 to 331 in fc8156d
The execution of this test triggers the following exception from
FGTable.cpp:jsbsim/src/math/FGTable.cpp
Lines 126 to 130 in fc8156d
In the Python binding, the method
FGFDMExec::LoadModelis set to use the exception handler from the functionconvertJSBSimToPyExc:jsbsim/python/jsbsim.pxd
Lines 218 to 219 in fc8156d
Since there is no
catchinstruction for theLogExceptiontype inconvertJSBSimToPyExc, the C++ exception is "converted" to a Python exceptionBaseError:jsbsim/python/src/ExceptionManagement.h
Lines 53 to 55 in fc8156d
THEN the C++ exception instance
eis destroyed which triggers the call to the destructorBufferLoggerwhich sets the logging level of theFGLoggerinstance stored inGlobalLogger(i.e. callsGlobalLogger::SetLevel):jsbsim/src/input_output/FGLog.cpp
Lines 116 to 120 in fc8156d
For that test, the logger is an instance of
PyLogger, soPyLogger::SetLevelis called:jsbsim/python/src/PyLogger.cxx
Lines 73 to 79 in fc8156d
And this is where the Python interpreter terminates the program since the Python method
set_levelis called while an exception has been raised by the earlier call toPyErr_SetStringinExceptionManagement.h.The fix
The idea is to catch the Python exception, to run the Python method
set_levelthen to re-throw the Python exception.For that purpose, the PR adds a new class
PyExceptionHandlerthat catches and re-throws Python exceptions using RAII:PyErr_Fetch.PyErr_Restore. The destructor also manages the case where the execution ofset_levelwould raise an exception. In that case, the new exception is considered "unraisable": it is written instderrthen discarded byPyErr_WriteUnraisable. (HoweverPyErr_WriteUnraisablecan be "intercepted" bysys.unraisablehookif one needs to detect their occurrence - see this blog post from the author of that feature).With the new class
PyExceptionHandler:LogExceptionthen the code proceed withset_levelotherwise it does nothing.PyExceptionHandleris executed, the exception is re-thrown (whatever the exception was), or nothing is done if no exception was raised.FGLogger.Note that I have created a new Python exception
LogExceptionErrorto be able to distinguish occurrences ofJSBSim::BaseExceptionfrom occurrences ofJSBSim::LogException. The methodset_levelis only executed when an occurrence of the latter is raised.