From dc0cf49d9858841c58c1cde41ad299e5d3a386ed Mon Sep 17 00:00:00 2001 From: Dominic Hirtler Date: Mon, 18 Oct 2021 18:03:31 +0200 Subject: [PATCH 01/16] signals: Add framework for printing function on signal --- src/util/signals.h | 3 +++ src/util/win/signals.c | 15 ++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/util/signals.h b/src/util/signals.h index f468ca7..744aa54 100644 --- a/src/util/signals.h +++ b/src/util/signals.h @@ -23,6 +23,9 @@ void mcx_signal_handler_enable(void); void mcx_signal_handler_set_name(const char * threadName); void mcx_signal_handler_unset_name(void); +void mcx_signal_handler_set_function(const char * functionName); +void mcx_signal_handler_unset_function(void); + /** * Deletes the handler for SIGSEGV */ diff --git a/src/util/win/signals.c b/src/util/win/signals.c index e584175..3a652d1 100644 --- a/src/util/win/signals.c +++ b/src/util/win/signals.c @@ -21,6 +21,7 @@ /* Thread local variable to store the name of the element which is * running inside the signal-handled block. */ __declspec( thread ) static const char * _signalThreadName = NULL; +__declspec( thread ) static const char * _signalFunctionName = NULL; #ifdef __cplusplus extern "C" { @@ -28,7 +29,11 @@ extern "C" { static LONG WINAPI HandleException(PEXCEPTION_POINTERS exception) { if (_signalThreadName) { - mcx_log(LOG_ERROR, "The element %s caused an unrecoverable error.", _signalThreadName); + if (_signalFunctionName) { + mcx_log(LOG_ERROR, "The element %s caused an unrecoverable error in %s.", _signalThreadName, _signalFunctionName); + } else { + mcx_log(LOG_ERROR, "The element %s caused an unrecoverable error.", _signalThreadName); + } } else { mcx_log(LOG_ERROR, "An element caused an unrecoverable error."); } @@ -112,6 +117,14 @@ void mcx_signal_handler_unset_name(void) { _signalThreadName = NULL; } +void mcx_signal_handler_set_function(const char * functionName) { + _signalFunctionName = functionName; +} + +void mcx_signal_handler_unset_function(void) { + _signalFunctionName = NULL; +} + void mcx_signal_handler_enable(void) { _signalThreadName = NULL; SetUnhandledExceptionFilter(HandleException); From 3a5774275f5d011b002056cbe04179143e558a4f Mon Sep 17 00:00:00 2001 From: Dominic Hirtler Date: Mon, 18 Oct 2021 18:04:26 +0200 Subject: [PATCH 02/16] signals: Upgrade current function storage to stack --- src/util/win/signals.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/util/win/signals.c b/src/util/win/signals.c index 3a652d1..833d4cf 100644 --- a/src/util/win/signals.c +++ b/src/util/win/signals.c @@ -22,6 +22,8 @@ * running inside the signal-handled block. */ __declspec( thread ) static const char * _signalThreadName = NULL; __declspec( thread ) static const char * _signalFunctionName = NULL; +__declspec( thread ) static const char * _signalFunctionNameStack1 = NULL; +__declspec( thread ) static const char * _signalFunctionNameStack2 = NULL; #ifdef __cplusplus extern "C" { @@ -118,11 +120,31 @@ void mcx_signal_handler_unset_name(void) { } void mcx_signal_handler_set_function(const char * functionName) { + if (_signalFunctionNameStack2 != NULL) { + mcx_log(LOG_ERROR, "Signal handler function callstack overflow!"); + exit(1); // I guess there is a better way to handle this + } + if (_signalFunctionNameStack1 != NULL) { + _signalFunctionNameStack2 = _signalFunctionNameStack1; + } + if (_signalFunctionName != NULL) { + _signalFunctionNameStack1 = _signalFunctionName; + } _signalFunctionName = functionName; } void mcx_signal_handler_unset_function(void) { - _signalFunctionName = NULL; + if (_signalFunctionName == NULL) { + mcx_log(LOG_WARNING, "Signal handler function callstack empty. Cannot pop non-existing element."); + } + if (_signalFunctionNameStack1 != NULL) { + _signalFunctionName = _signalFunctionNameStack1; + if (_signalFunctionNameStack2 != NULL) { + _signalFunctionNameStack1 = _signalFunctionNameStack2; + } + } else { + _signalFunctionName = NULL; + } } void mcx_signal_handler_enable(void) { From 31a96326623ab835da6b640c32a596f924babf89 Mon Sep 17 00:00:00 2001 From: Dominic Hirtler Date: Tue, 19 Oct 2021 14:15:09 +0200 Subject: [PATCH 03/16] signals: Add possibility to omit redundant argument --- src/util/signals.h | 8 +++++++- src/util/win/signals.c | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/util/signals.h b/src/util/signals.h index 744aa54..e7fb6d2 100644 --- a/src/util/signals.h +++ b/src/util/signals.h @@ -23,7 +23,13 @@ void mcx_signal_handler_enable(void); void mcx_signal_handler_set_name(const char * threadName); void mcx_signal_handler_unset_name(void); -void mcx_signal_handler_set_function(const char * functionName); +/** + * Sets and unsets the current functions name for usage in signal handler messages + * + * Note: __func__ is part of C99 standard (ISO/IEC 9899:1999), section 6.4.2.2 + */ +#define mcx_signal_handler_set_function() mcx_signal_handler_set_function_internal(__func__) +void mcx_signal_handler_set_function_internal(const char * functionName); void mcx_signal_handler_unset_function(void); /** diff --git a/src/util/win/signals.c b/src/util/win/signals.c index 833d4cf..0930867 100644 --- a/src/util/win/signals.c +++ b/src/util/win/signals.c @@ -119,7 +119,7 @@ void mcx_signal_handler_unset_name(void) { _signalThreadName = NULL; } -void mcx_signal_handler_set_function(const char * functionName) { +void mcx_signal_handler_set_function_internal(const char * functionName) { if (_signalFunctionNameStack2 != NULL) { mcx_log(LOG_ERROR, "Signal handler function callstack overflow!"); exit(1); // I guess there is a better way to handle this From 2fffc22e2e3cab29abef7ac762b085976ddc1ed0 Mon Sep 17 00:00:00 2001 From: Dominic Hirtler Date: Tue, 19 Oct 2021 14:16:05 +0200 Subject: [PATCH 04/16] signals: Add get for function name --- src/util/signals.h | 1 + src/util/win/signals.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/util/signals.h b/src/util/signals.h index e7fb6d2..a537be1 100644 --- a/src/util/signals.h +++ b/src/util/signals.h @@ -47,6 +47,7 @@ void mcx_signal_handler_sigint(int param); */ int mcx_signal_handler_is_interrupted(void); +const char * mcx_signal_handler_get_function_name(void); #ifdef __cplusplus } /* closing brace for extern "C" */ diff --git a/src/util/win/signals.c b/src/util/win/signals.c index 0930867..52d8757 100644 --- a/src/util/win/signals.c +++ b/src/util/win/signals.c @@ -159,6 +159,10 @@ void mcx_signal_handler_disable(void) { _signalThreadName = NULL; } +const char * mcx_signal_handler_get_function_name(void) { + return _signalFunctionName; +} + #ifdef __cplusplus } /* closing brace for extern "C" */ #endif /* __cplusplus */ \ No newline at end of file From b6fb3eddaa19c12d20efcd60d8495c37d90d2031 Mon Sep 17 00:00:00 2001 From: Dominic Hirtler Date: Tue, 19 Oct 2021 14:46:22 +0200 Subject: [PATCH 05/16] signals: Add function name to error message on linux --- src/util/linux/signals.c | 41 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/util/linux/signals.c b/src/util/linux/signals.c index aecd9de..d6735b0 100644 --- a/src/util/linux/signals.c +++ b/src/util/linux/signals.c @@ -18,6 +18,9 @@ /* Thread local variable to store the name of the element which is * running inside the signal-handled block. */ static __thread const char * _signalThreadName = NULL; +static __thread const char * _signalFunctionName = NULL; +static __thread const char * _signalFunctionNameStack1 = NULL; +static __thread const char * _signalFunctionNameStack2 = NULL; #ifdef __cplusplus extern "C" { @@ -25,7 +28,11 @@ extern "C" { static void sigHandlerParam(int param) { if (_signalThreadName) { - mcx_log(LOG_ERROR, "The element %s caused an unrecoverable error. Shutting down.", _signalThreadName); + if (_signalFunctionName) { + mcx_log(LOG_ERROR, "The element %s caused an unrecoverable error in %s. Shutting down.", _signalThreadName, _signalFunctionName); + } else { + mcx_log(LOG_ERROR, "The element %s caused an unrecoverable error. Shutting down.", _signalThreadName); + } } else { mcx_log(LOG_ERROR, "An element caused an unrecoverable error. Shutting down."); } @@ -48,6 +55,34 @@ void mcx_signal_handler_unset_name(void) { _signalThreadName = NULL; } +void mcx_signal_handler_set_function_internal(const char * functionName) { + if (_signalFunctionNameStack2 != NULL) { + mcx_log(LOG_ERROR, "Signal handler function callstack overflow!"); + exit(1); // I guess there is a better way to handle this + } + if (_signalFunctionNameStack1 != NULL) { + _signalFunctionNameStack2 = _signalFunctionNameStack1; + } + if (_signalFunctionName != NULL) { + _signalFunctionNameStack1 = _signalFunctionName; + } + _signalFunctionName = functionName; +} + +void mcx_signal_handler_unset_function(void) { + if (_signalFunctionName == NULL) { + mcx_log(LOG_WARNING, "Signal handler function callstack empty. Cannot pop non-existing element."); + } + if (_signalFunctionNameStack1 != NULL) { + _signalFunctionName = _signalFunctionNameStack1; + if (_signalFunctionNameStack2 != NULL) { + _signalFunctionNameStack1 = _signalFunctionNameStack2; + } + } else { + _signalFunctionName = NULL; + } +} + void mcx_signal_handler_enable(void) { static struct sigaction sigHandlerSEGV; @@ -71,6 +106,10 @@ void mcx_signal_handler_disable(void) { _signalThreadName = NULL; } +const char * mcx_signal_handler_get_function_name(void) { + return _signalFunctionName; +} + #ifdef __cplusplus } /* closing brace for extern "C" */ From 195f272409660e17ff0814dbb9af36002543d3cb Mon Sep 17 00:00:00 2001 From: Dominic Hirtler Date: Wed, 27 Oct 2021 15:44:14 +0200 Subject: [PATCH 06/16] signals: Log function on error in component dosteps --- src/components/comp_fmu.c | 3 +++ src/core/Component.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/components/comp_fmu.c b/src/components/comp_fmu.c index 8dd698c..56ab7b1 100644 --- a/src/components/comp_fmu.c +++ b/src/components/comp_fmu.c @@ -21,6 +21,7 @@ #include "objects/Map.h" #include "reader/model/components/specific_data/FmuInput.h" #include "util/string.h" +#include "util/signals.h" #ifdef __cplusplus extern "C" { @@ -987,7 +988,9 @@ static McxStatus Fmu2DoStep(Component * comp, size_t group, double time, double TimeSnapshotEnd(&comp->data->rtData.funcTimings.rtInput); // Do calculations + mcx_signal_handler_set_function("fmi2_import_do_step"); status = fmi2_import_do_step(fmu2->fmiImport, compFmu->lastCommunicationTimePoint, deltaTime, fmi2_true); + mcx_signal_handler_unset_function(); if (fmi2_status_ok == status) { // fine } else if (fmi2_status_discard == status) { diff --git a/src/core/Component.c b/src/core/Component.c index eb05b1c..a533d95 100644 --- a/src/core/Component.c +++ b/src/core/Component.c @@ -503,7 +503,9 @@ McxStatus ComponentDoStep(Component * comp, size_t group, double time, double de if (comp->DoStep) { mcx_signal_handler_set_name(comp->GetName(comp)); + mcx_signal_handler_set_this_function(); retVal = comp->DoStep(comp, group, time, deltaTime, endTime, isNewStep); + mcx_signal_handler_unset_function(); mcx_signal_handler_unset_name(); if (RETURN_OK != retVal) { ComponentLog(comp, LOG_DEBUG, "Component specific DoStep failed"); From 0d789f32515eb1750aa98053e10c6d7ed7a3911d Mon Sep 17 00:00:00 2001 From: Dominic Hirtler Date: Wed, 27 Oct 2021 15:47:43 +0200 Subject: [PATCH 07/16] signals: Improve naming of functions --- src/util/linux/signals.c | 2 +- src/util/signals.h | 4 ++-- src/util/win/signals.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/util/linux/signals.c b/src/util/linux/signals.c index d6735b0..1e84ea0 100644 --- a/src/util/linux/signals.c +++ b/src/util/linux/signals.c @@ -55,7 +55,7 @@ void mcx_signal_handler_unset_name(void) { _signalThreadName = NULL; } -void mcx_signal_handler_set_function_internal(const char * functionName) { +void mcx_signal_handler_set_function(const char * functionName) { if (_signalFunctionNameStack2 != NULL) { mcx_log(LOG_ERROR, "Signal handler function callstack overflow!"); exit(1); // I guess there is a better way to handle this diff --git a/src/util/signals.h b/src/util/signals.h index a537be1..b1a3ee0 100644 --- a/src/util/signals.h +++ b/src/util/signals.h @@ -28,8 +28,8 @@ void mcx_signal_handler_unset_name(void); * * Note: __func__ is part of C99 standard (ISO/IEC 9899:1999), section 6.4.2.2 */ -#define mcx_signal_handler_set_function() mcx_signal_handler_set_function_internal(__func__) -void mcx_signal_handler_set_function_internal(const char * functionName); +#define mcx_signal_handler_set_this_function() mcx_signal_handler_set_function(__func__) +void mcx_signal_handler_set_function(const char * functionName); void mcx_signal_handler_unset_function(void); /** diff --git a/src/util/win/signals.c b/src/util/win/signals.c index 52d8757..fba8149 100644 --- a/src/util/win/signals.c +++ b/src/util/win/signals.c @@ -119,7 +119,7 @@ void mcx_signal_handler_unset_name(void) { _signalThreadName = NULL; } -void mcx_signal_handler_set_function_internal(const char * functionName) { +void mcx_signal_handler_set_function(const char * functionName) { if (_signalFunctionNameStack2 != NULL) { mcx_log(LOG_ERROR, "Signal handler function callstack overflow!"); exit(1); // I guess there is a better way to handle this From 72d3a5515bcc0b894a0b9856e752069bca1f3987 Mon Sep 17 00:00:00 2001 From: Dominic Hirtler Date: Wed, 27 Oct 2021 15:48:31 +0200 Subject: [PATCH 08/16] signals: Make callstack handling faster and more straight forward --- src/util/linux/signals.c | 19 +++++-------------- src/util/win/signals.c | 21 ++++++--------------- 2 files changed, 11 insertions(+), 29 deletions(-) diff --git a/src/util/linux/signals.c b/src/util/linux/signals.c index 1e84ea0..a5fa976 100644 --- a/src/util/linux/signals.c +++ b/src/util/linux/signals.c @@ -60,12 +60,8 @@ void mcx_signal_handler_set_function(const char * functionName) { mcx_log(LOG_ERROR, "Signal handler function callstack overflow!"); exit(1); // I guess there is a better way to handle this } - if (_signalFunctionNameStack1 != NULL) { - _signalFunctionNameStack2 = _signalFunctionNameStack1; - } - if (_signalFunctionName != NULL) { - _signalFunctionNameStack1 = _signalFunctionName; - } + _signalFunctionNameStack2 = _signalFunctionNameStack1; + _signalFunctionNameStack1 = _signalFunctionName; _signalFunctionName = functionName; } @@ -73,14 +69,9 @@ void mcx_signal_handler_unset_function(void) { if (_signalFunctionName == NULL) { mcx_log(LOG_WARNING, "Signal handler function callstack empty. Cannot pop non-existing element."); } - if (_signalFunctionNameStack1 != NULL) { - _signalFunctionName = _signalFunctionNameStack1; - if (_signalFunctionNameStack2 != NULL) { - _signalFunctionNameStack1 = _signalFunctionNameStack2; - } - } else { - _signalFunctionName = NULL; - } + _signalFunctionName = _signalFunctionNameStack1; + _signalFunctionNameStack1 = _signalFunctionNameStack2; + _signalFunctionNameStack2 = NULL; } void mcx_signal_handler_enable(void) { diff --git a/src/util/win/signals.c b/src/util/win/signals.c index fba8149..f434af1 100644 --- a/src/util/win/signals.c +++ b/src/util/win/signals.c @@ -124,27 +124,18 @@ void mcx_signal_handler_set_function(const char * functionName) { mcx_log(LOG_ERROR, "Signal handler function callstack overflow!"); exit(1); // I guess there is a better way to handle this } - if (_signalFunctionNameStack1 != NULL) { - _signalFunctionNameStack2 = _signalFunctionNameStack1; - } - if (_signalFunctionName != NULL) { - _signalFunctionNameStack1 = _signalFunctionName; - } + _signalFunctionNameStack2 = _signalFunctionNameStack1; + _signalFunctionNameStack1 = _signalFunctionName; _signalFunctionName = functionName; } void mcx_signal_handler_unset_function(void) { if (_signalFunctionName == NULL) { - mcx_log(LOG_WARNING, "Signal handler function callstack empty. Cannot pop non-existing element."); - } - if (_signalFunctionNameStack1 != NULL) { - _signalFunctionName = _signalFunctionNameStack1; - if (_signalFunctionNameStack2 != NULL) { - _signalFunctionNameStack1 = _signalFunctionNameStack2; - } - } else { - _signalFunctionName = NULL; + mcx_log(LOG_WARNING, "Signal handler function callstack in element %s empty. Cannot pop non-existing element.", _signalThreadName); } + _signalFunctionName = _signalFunctionNameStack1; + _signalFunctionNameStack1 = _signalFunctionNameStack2; + _signalFunctionNameStack2 = NULL; } void mcx_signal_handler_enable(void) { From 6633767498def1ed24fdc112580669608c7cdf4c Mon Sep 17 00:00:00 2001 From: Dominic Hirtler Date: Wed, 16 Feb 2022 11:55:24 +0100 Subject: [PATCH 09/16] signals: Check stack integrity only on Debug --- src/util/linux/signals.c | 4 ++++ src/util/win/signals.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/util/linux/signals.c b/src/util/linux/signals.c index a5fa976..aede221 100644 --- a/src/util/linux/signals.c +++ b/src/util/linux/signals.c @@ -56,19 +56,23 @@ void mcx_signal_handler_unset_name(void) { } void mcx_signal_handler_set_function(const char * functionName) { +#if defined(MCX_DEBUG) if (_signalFunctionNameStack2 != NULL) { mcx_log(LOG_ERROR, "Signal handler function callstack overflow!"); exit(1); // I guess there is a better way to handle this } +#endif _signalFunctionNameStack2 = _signalFunctionNameStack1; _signalFunctionNameStack1 = _signalFunctionName; _signalFunctionName = functionName; } void mcx_signal_handler_unset_function(void) { +#if defined(MCX_DEBUG) if (_signalFunctionName == NULL) { mcx_log(LOG_WARNING, "Signal handler function callstack empty. Cannot pop non-existing element."); } +#endif _signalFunctionName = _signalFunctionNameStack1; _signalFunctionNameStack1 = _signalFunctionNameStack2; _signalFunctionNameStack2 = NULL; diff --git a/src/util/win/signals.c b/src/util/win/signals.c index f434af1..f6c83ec 100644 --- a/src/util/win/signals.c +++ b/src/util/win/signals.c @@ -120,19 +120,23 @@ void mcx_signal_handler_unset_name(void) { } void mcx_signal_handler_set_function(const char * functionName) { +#if defined(MCX_DEBUG) if (_signalFunctionNameStack2 != NULL) { mcx_log(LOG_ERROR, "Signal handler function callstack overflow!"); exit(1); // I guess there is a better way to handle this } +#endif _signalFunctionNameStack2 = _signalFunctionNameStack1; _signalFunctionNameStack1 = _signalFunctionName; _signalFunctionName = functionName; } void mcx_signal_handler_unset_function(void) { +#if defined(MCX_DEBUG) if (_signalFunctionName == NULL) { mcx_log(LOG_WARNING, "Signal handler function callstack in element %s empty. Cannot pop non-existing element.", _signalThreadName); } +#endif _signalFunctionName = _signalFunctionNameStack1; _signalFunctionNameStack1 = _signalFunctionNameStack2; _signalFunctionNameStack2 = NULL; From 7c867320b696ca57cc9e2dc147736a04914693c7 Mon Sep 17 00:00:00 2001 From: Dominic Hirtler Date: Tue, 8 Mar 2022 15:05:20 +0100 Subject: [PATCH 10/16] signals: Populate call stack more often --- mcx/mcx.c | 24 ++++++++++++++++++++++++ src/core/Task.c | 6 ++++++ 2 files changed, 30 insertions(+) diff --git a/mcx/mcx.c b/mcx/mcx.c index c5c0f43..fa5749c 100644 --- a/mcx/mcx.c +++ b/mcx/mcx.c @@ -316,14 +316,20 @@ McxStatus RunMCX(int argc, char *argv[]) { goto cleanup; } + mcx_signal_handler_set_function("ConfigSetupFromCmdLine"); retVal = config->SetupFromCmdLine(config, argc, argv); + mcx_signal_handler_unset_function(); if (retVal == RETURN_ERROR) { goto cleanup; } + mcx_signal_handler_set_function("SetupLogFiles"); SetupLogFiles(config->logFile, config->writeAllLogFile); + mcx_signal_handler_unset_function(); logInitialized = 1; + mcx_signal_handler_set_function("ConfigSetupFromEnvironment"); retVal = config->SetupFromEnvironment(config); + mcx_signal_handler_unset_function(); if (RETURN_OK != retVal) { mcx_log(LOG_INFO, "Setting up configuration from environment failed"); retVal = RETURN_ERROR; @@ -337,14 +343,18 @@ McxStatus RunMCX(int argc, char *argv[]) { goto cleanup; } + mcx_signal_handler_set_function("ReaderSetup"); retVal = reader->Setup(reader, config->modelFile, config); + mcx_signal_handler_unset_function(); if (retVal == RETURN_ERROR) { mcx_log(LOG_ERROR, "Input reader setup failed"); retVal = RETURN_ERROR; goto cleanup; } + mcx_signal_handler_set_function("ReaderRead"); mcxInput = reader->Read(reader, config->modelFile); + mcx_signal_handler_unset_function(); if (!mcxInput) { mcx_log(LOG_ERROR, "Parsing of input file failed"); retVal = RETURN_ERROR; @@ -352,7 +362,9 @@ McxStatus RunMCX(int argc, char *argv[]) { } element = (InputElement *) mcxInput; + mcx_signal_handler_set_function("ConfigSetupFromInput"); retVal = config->SetupFromInput(config, mcxInput->config); + mcx_signal_handler_unset_function(); if (RETURN_OK != retVal) { mcx_log(LOG_ERROR, "Setting up configuration from input file failed"); retVal = RETURN_ERROR; @@ -387,20 +399,26 @@ McxStatus RunMCX(int argc, char *argv[]) { mcx_cpu_time_get(&clock_read_begin); mcx_time_get(&time_read_begin); + mcx_signal_handler_set_function("TaskRead"); retVal = task->Read(task, mcxInput->task); + mcx_signal_handler_unset_function(); if (RETURN_OK != retVal) { retVal = RETURN_ERROR; goto cleanup; } + mcx_signal_handler_set_function("ModelRead"); retVal = model->Read(model, mcxInput->model); + mcx_signal_handler_unset_function(); if (RETURN_OK != retVal) { retVal = RETURN_ERROR; goto cleanup; } object_destroy(mcxInput); + mcx_signal_handler_set_function("ReaderCleanup"); reader->Cleanup(reader); + mcx_signal_handler_unset_function(); object_destroy(reader); mcx_cpu_time_get(&clock_read_end); @@ -421,19 +439,25 @@ McxStatus RunMCX(int argc, char *argv[]) { mcx_cpu_time_get(&clock_setup_begin); mcx_time_get(&time_setup_begin); + mcx_signal_handler_set_function("TaskSetup"); retVal = task->Setup(task, model); + mcx_signal_handler_unset_function(); if (RETURN_OK != retVal) { retVal = RETURN_ERROR; goto cleanup; } + mcx_signal_handler_set_function("ModelSetup"); retVal = model->Setup(model); + mcx_signal_handler_unset_function(); if (RETURN_OK != retVal) { retVal = RETURN_ERROR; goto cleanup; } + mcx_signal_handler_set_function("TaskPrepareRun"); retVal = task->PrepareRun(task, model); + mcx_signal_handler_unset_function(); if (RETURN_OK != retVal) { retVal = RETURN_ERROR; goto cleanup; diff --git a/src/core/Task.c b/src/core/Task.c index 33303dc..b9eb6f8 100644 --- a/src/core/Task.c +++ b/src/core/Task.c @@ -84,19 +84,25 @@ static McxStatus TaskPrepareRun(Task * task, Model * model) { McxStatus retVal = RETURN_OK; #if defined (ENABLE_STORAGE) + mcx_signal_handler_set_function("ResultsStorageSetup"); retVal = task->storage->Setup(task->storage, task->timeStart); + mcx_signal_handler_unset_function(); if (RETURN_OK != retVal) { mcx_log(LOG_ERROR, "Could not setup storage"); return RETURN_ERROR; } + mcx_signal_handler_set_function("ResultsStorageAddModelComponents"); retVal = task->storage->AddModelComponents(task->storage, model->subModel); + mcx_signal_handler_unset_function(); if (RETURN_OK != retVal) { mcx_log(LOG_ERROR, "Could not setup component storage"); return RETURN_ERROR; } + mcx_signal_handler_set_function("ResultsStorageSetupBackends"); retVal = task->storage->SetupBackends(task->storage); + mcx_signal_handler_unset_function(); if (RETURN_OK != retVal) { mcx_log(LOG_ERROR, "Could not setup storage backends"); return RETURN_ERROR; From 2983350ff4840229d178850b5459ddbf2ffd5897 Mon Sep 17 00:00:00 2001 From: Dominic Hirtler Date: Tue, 15 Mar 2022 15:08:27 +0100 Subject: [PATCH 11/16] signals: Populate call stack on important blocks --- mcx/mcx.c | 4 ++++ src/core/Task.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/mcx/mcx.c b/mcx/mcx.c index fa5749c..4d19356 100644 --- a/mcx/mcx.c +++ b/mcx/mcx.c @@ -481,7 +481,9 @@ McxStatus RunMCX(int argc, char *argv[]) { mcx_cpu_time_get(&clock_init_begin); mcx_time_get(&time_init_begin); + mcx_signal_handler_set_function("TaskInitialize"); retVal = task->Initialize(task, model); + mcx_signal_handler_unset_function(); if (RETURN_OK != retVal) { retVal = RETURN_ERROR; goto cleanup; @@ -505,7 +507,9 @@ McxStatus RunMCX(int argc, char *argv[]) { mcx_log(LOG_INFO, " "); mcx_cpu_time_get(&clock_sim_begin); mcx_time_get(&time_sim_begin); + mcx_signal_handler_set_function("TaskRun"); retVal = task->Run(task, model); + mcx_signal_handler_unset_function(); if (RETURN_OK != retVal) { retVal = RETURN_ERROR; goto cleanup; diff --git a/src/core/Task.c b/src/core/Task.c index b9eb6f8..4882a82 100644 --- a/src/core/Task.c +++ b/src/core/Task.c @@ -160,7 +160,9 @@ static McxStatus TaskRun(Task * task, Model * model) { stepParams->timeEndStep += task->params->timeStepSize; } + mcx_signal_handler_set_function("StepTypeDoStep"); status = task->stepType->DoStep(task->stepType, stepParams, subModel); + mcx_signal_handler_unset_function(); if (status != RETURN_OK) { break; } From 9ccabe880abf043a48ad61c2360b99499eba15f9 Mon Sep 17 00:00:00 2001 From: Dominic Hirtler Date: Fri, 18 Mar 2022 10:56:49 +0100 Subject: [PATCH 12/16] signals: Populate call stack around cleanup --- mcx/mcx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mcx/mcx.c b/mcx/mcx.c index 4d19356..c180997 100644 --- a/mcx/mcx.c +++ b/mcx/mcx.c @@ -540,6 +540,7 @@ McxStatus RunMCX(int argc, char *argv[]) { mcx_cpu_time_get(&clock_cleanup_begin); mcx_time_get(&time_cleanup_begin); + mcx_signal_handler_set_function("RunMCX:Cleanup"); object_destroy(task); object_destroy(model); object_destroy(config); @@ -582,6 +583,7 @@ McxStatus RunMCX(int argc, char *argv[]) { mcx_log(LOG_INFO, "**********************************************************************"); } + mcx_signal_handler_unset_function(); // RunMCX:Cleanup return retVal; } From 57483aa91f69b99150d97d8228043561aa599e48 Mon Sep 17 00:00:00 2001 From: Dominic Hirtler Date: Tue, 22 Mar 2022 13:20:52 +0100 Subject: [PATCH 13/16] signals: Populate call stack on fmu calls --- src/components/comp_fmu.c | 20 ++++++++++++++++++++ src/fmu/common_fmu2.c | 23 +++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/src/components/comp_fmu.c b/src/components/comp_fmu.c index 56ab7b1..8496501 100644 --- a/src/components/comp_fmu.c +++ b/src/components/comp_fmu.c @@ -230,10 +230,12 @@ static McxStatus Fmu1Initialize(Component * comp, size_t group, double startTime // Initialization Mode ComponentLog(comp, LOG_DEBUG, "fmiInitializeSlave"); + mcx_signal_handler_set_function("fmi1_import_initialize_slave"); status = fmi1_import_initialize_slave(fmu1->fmiImport, startTime, fmi1_false, 0.0); + mcx_signal_handler_unset_function(); if (fmi1_status_ok != status) { ComponentLog(comp, LOG_ERROR, "fmiInitializeSlave failed"); return RETURN_ERROR; @@ -289,7 +291,9 @@ static McxStatus Fmu1DoStep(Component * comp, size_t group, double time, double } // Do calculations + mcx_signal_handler_set_function("fmi1_import_do_step"); status = fmi1_import_do_step(fmu1->fmiImport, compFmu->lastCommunicationTimePoint, deltaTime, fmi1_true); + mcx_signal_handler_unset_function(); if (fmi1_status_ok == status) { // fine } else if (fmi1_status_discard == status) { @@ -906,12 +910,14 @@ static McxStatus Fmu2Initialize(Component * comp, size_t group, double startTime defaultTolerance = fmi2_import_get_default_experiment_tolerance(fmu2->fmiImport); compFmu->lastCommunicationTimePoint = startTime; + mcx_signal_handler_set_function("fmi2_import_setup_experiment"); status = fmi2_import_setup_experiment(fmu2->fmiImport, fmi2_false, /* toleranceDefine */ defaultTolerance, startTime, /* startTime */ fmi2_false, /* stopTimeDefined */ 0.0 /* stopTime */); + mcx_signal_handler_unset_function(); if (fmi2_status_ok != status) { ComponentLog(comp, LOG_ERROR, "SetupExperiment failed"); @@ -919,7 +925,9 @@ static McxStatus Fmu2Initialize(Component * comp, size_t group, double startTime } // Initialization Mode + mcx_signal_handler_set_function("fmi2_import_enter_initialization_mode"); status = fmi2_import_enter_initialization_mode(fmu2->fmiImport); + mcx_signal_handler_unset_function(); if (fmi2_status_ok != status) { ComponentLog(comp, LOG_ERROR, "Could not enter Initialization Mode"); return RETURN_ERROR; @@ -962,7 +970,9 @@ static McxStatus Fmu2Initialize(Component * comp, size_t group, double startTime static McxStatus Fmu2ExitInitializationMode(Component *comp) { CompFMU *compFmu = (CompFMU*)comp; + mcx_signal_handler_set_function("fmi2_import_exit_initialization_mode"); fmi2_status_t status = fmi2_import_exit_initialization_mode(compFmu->fmu2.fmiImport); + mcx_signal_handler_unset_function(); if (fmi2_status_ok != status) { ComponentLog(comp, LOG_ERROR, "Could not exit Initialization Mode"); return RETURN_ERROR; @@ -997,7 +1007,9 @@ static McxStatus Fmu2DoStep(Component * comp, size_t group, double time, double fmi2_status_t fmi2status; fmi2_boolean_t isTerminated = fmi2_false; + mcx_signal_handler_set_function("fmi2_import_get_boolean_status"); fmi2status = fmi2_import_get_boolean_status(fmu2->fmiImport, fmi2_terminated, &isTerminated); + mcx_signal_handler_unset_function(); if (fmi2_status_ok == fmi2status) { if (fmi2_true == isTerminated) { comp->SetIsFinished(comp); @@ -1333,21 +1345,29 @@ static void CompFMUDestructor(CompFMU * compFmu) { // TOOD: Move this to the common struct destructors if (fmu1->fmiImport) { if (fmi1_true == fmu1->runOk) { + mcx_signal_handler_set_function("fmi1_import_terminate_slave"); fmi1_import_terminate_slave(fmu1->fmiImport); + mcx_signal_handler_unset_function(); } if (fmi1_true == fmu1->instantiateOk) { + mcx_signal_handler_set_function("fmi1_import_free_slave_instance"); fmi1_import_free_slave_instance(fmu1->fmiImport); + mcx_signal_handler_unset_function(); } } if (fmu2->fmiImport) { if (fmi2_true == fmu2->runOk) { + mcx_signal_handler_set_function("fmi2_import_terminate"); fmi2_import_terminate(fmu2->fmiImport); + mcx_signal_handler_unset_function(); } if (fmi2_true == fmu2->instantiateOk) { + mcx_signal_handler_set_function("fmi2_import_free_instance"); fmi2_import_free_instance(fmu2->fmiImport); + mcx_signal_handler_unset_function(); } } diff --git a/src/fmu/common_fmu2.c b/src/fmu/common_fmu2.c index 21c1040..27c75b2 100644 --- a/src/fmu/common_fmu2.c +++ b/src/fmu/common_fmu2.c @@ -21,6 +21,7 @@ #include "util/string.h" #include "util/stdlib.h" +#include "util/signals.h" #include "fmilib.h" @@ -191,11 +192,13 @@ McxStatus Fmu2CommonStructSetup(FmuCommon * common, Fmu2CommonStruct * fmu2, fmi } mcx_log(LOG_DEBUG, "%s: instantiatefn: %x", common->instanceName, fmi2_import_instantiate); + mcx_signal_handler_set_function("fmi2_import_instantiate"), jmStatus = fmi2_import_instantiate(fmu2->fmiImport, common->instanceName, fmu_type, NULL, fmi2_false /* visible */); + mcx_signal_handler_unset_function(); if (jm_status_error == jmStatus) { mcx_log(LOG_ERROR, "%s: Instantiate failed", common->instanceName); return RETURN_ERROR; @@ -634,7 +637,9 @@ McxStatus Fmu2SetVariable(Fmu2CommonStruct * fmu, Fmu2Value * fmuVal) { { fmi2_value_reference_t vr[] = {fmuVal->data->vr.scalar}; + mcx_signal_handler_set_function("fmi2_import_set_real"); status = fmi2_import_set_real(fmu->fmiImport, vr, 1, (const fmi2_real_t *) ChannelValueReference(chVal)); + mcx_signal_handler_unset_function(); MCX_DEBUG_LOG("Set %s(%d)=%f", fmuVal->name, vr[0], *(double*)ChannelValueReference(chVal)); @@ -644,7 +649,9 @@ McxStatus Fmu2SetVariable(Fmu2CommonStruct * fmu, Fmu2Value * fmuVal) { { fmi2_value_reference_t vr[] = { fmuVal->data->vr.scalar }; + mcx_signal_handler_set_function("fmi2_import_set_integer"); status = fmi2_import_set_integer(fmu->fmiImport, vr, 1, (const fmi2_integer_t *) ChannelValueReference(chVal)); + mcx_signal_handler_unset_function(); MCX_DEBUG_LOG("Set %s(%d)=%d", fmuVal->name, vr[0], *(int*)ChannelValueReference(chVal)); @@ -654,7 +661,9 @@ McxStatus Fmu2SetVariable(Fmu2CommonStruct * fmu, Fmu2Value * fmuVal) { { fmi2_value_reference_t vr[] = { fmuVal->data->vr.scalar }; + mcx_signal_handler_set_function("fmi2_import_set_boolean"); status = fmi2_import_set_boolean(fmu->fmiImport, vr, 1, (const fmi2_boolean_t *) ChannelValueReference(chVal)); + mcx_signal_handler_unset_function(); break; } @@ -662,7 +671,9 @@ McxStatus Fmu2SetVariable(Fmu2CommonStruct * fmu, Fmu2Value * fmuVal) { { fmi2_value_reference_t vr[] = { fmuVal->data->vr.scalar }; + mcx_signal_handler_set_function("fmi2_import_set_string"); status = fmi2_import_set_string(fmu->fmiImport, vr, 1, (fmi2_string_t *) ChannelValueReference(chVal)); + mcx_signal_handler_unset_function(); break; } @@ -681,7 +692,9 @@ McxStatus Fmu2SetVariable(Fmu2CommonStruct * fmu, Fmu2Value * fmuVal) { , (fmi2_integer_t) binary->len }; + mcx_signal_handler_set_function("fmi2_import_set_integer"); status = fmi2_import_set_integer(fmu->fmiImport, vrs, 3, vals); + mcx_signal_handler_unset_function(); break; } @@ -738,7 +751,9 @@ McxStatus Fmu2GetVariable(Fmu2CommonStruct * fmu, Fmu2Value * fmuVal) { { fmi2_value_reference_t vr[] = { fmuVal->data->vr.scalar }; + mcx_signal_handler_set_function("fmi2_import_get_real"); status = fmi2_import_get_real(fmu->fmiImport, vr, 1, (fmi2_real_t *) ChannelValueReference(chVal)); + mcx_signal_handler_unset_function(); MCX_DEBUG_LOG("Get %s(%d)=%f", fmuVal->name, vr[0], *(double*)ChannelValueReference(chVal)); @@ -748,7 +763,9 @@ McxStatus Fmu2GetVariable(Fmu2CommonStruct * fmu, Fmu2Value * fmuVal) { { fmi2_value_reference_t vr[] = { fmuVal->data->vr.scalar }; + mcx_signal_handler_set_function("fmi2_import_get_integer"); status = fmi2_import_get_integer(fmu->fmiImport, vr, 1, (fmi2_integer_t *) ChannelValueReference(chVal)); + mcx_signal_handler_unset_function(); break; } @@ -756,7 +773,9 @@ McxStatus Fmu2GetVariable(Fmu2CommonStruct * fmu, Fmu2Value * fmuVal) { { fmi2_value_reference_t vr[] = { fmuVal->data->vr.scalar }; + mcx_signal_handler_set_function("fmi2_import_get_boolean"); status = fmi2_import_get_boolean(fmu->fmiImport, vr, 1, (fmi2_boolean_t *) ChannelValueReference(chVal)); + mcx_signal_handler_unset_function(); break; } @@ -766,7 +785,9 @@ McxStatus Fmu2GetVariable(Fmu2CommonStruct * fmu, Fmu2Value * fmuVal) { char * buffer = NULL; + mcx_signal_handler_set_function("fmi2_import_get_string"); status = fmi2_import_get_string(fmu->fmiImport, vr, 1, (fmi2_string_t *) &buffer); + mcx_signal_handler_unset_function(); ChannelValueSetFromReference(chVal, &buffer); break; @@ -783,7 +804,9 @@ McxStatus Fmu2GetVariable(Fmu2CommonStruct * fmu, Fmu2Value * fmuVal) { binary_string binary; + mcx_signal_handler_set_function("fmi2_import_get_integer"); status = fmi2_import_get_integer(fmu->fmiImport, vrs, 3, vs); + mcx_signal_handler_unset_function(); binary.len = vs[2]; binary.data = (char *) ((((long long)vs[1] & 0xffffffff) << 32) | (vs[0] & 0xffffffff)); From 229dd4d2bfa75b2b88c7cbdbfcd5009589914a02 Mon Sep 17 00:00:00 2001 From: Dominic Hirtler Date: Thu, 24 Mar 2022 11:24:19 +0100 Subject: [PATCH 14/16] signals: Increase call stack size 3->5 --- src/util/linux/signals.c | 10 ++++++++-- src/util/win/signals.c | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/util/linux/signals.c b/src/util/linux/signals.c index aede221..101e510 100644 --- a/src/util/linux/signals.c +++ b/src/util/linux/signals.c @@ -21,6 +21,8 @@ static __thread const char * _signalThreadName = NULL; static __thread const char * _signalFunctionName = NULL; static __thread const char * _signalFunctionNameStack1 = NULL; static __thread const char * _signalFunctionNameStack2 = NULL; +static __thread const char * _signalFunctionNameStack3 = NULL; +static __thread const char * _signalFunctionNameStack4 = NULL; #ifdef __cplusplus extern "C" { @@ -57,11 +59,13 @@ void mcx_signal_handler_unset_name(void) { void mcx_signal_handler_set_function(const char * functionName) { #if defined(MCX_DEBUG) - if (_signalFunctionNameStack2 != NULL) { + if (_signalFunctionNameStack4 != NULL) { mcx_log(LOG_ERROR, "Signal handler function callstack overflow!"); exit(1); // I guess there is a better way to handle this } #endif + _signalFunctionNameStack4 = _signalFunctionNameStack3; + _signalFunctionNameStack3 = _signalFunctionNameStack2; _signalFunctionNameStack2 = _signalFunctionNameStack1; _signalFunctionNameStack1 = _signalFunctionName; _signalFunctionName = functionName; @@ -75,7 +79,9 @@ void mcx_signal_handler_unset_function(void) { #endif _signalFunctionName = _signalFunctionNameStack1; _signalFunctionNameStack1 = _signalFunctionNameStack2; - _signalFunctionNameStack2 = NULL; + _signalFunctionNameStack2 = _signalFunctionNameStack3; + _signalFunctionNameStack3 = _signalFunctionNameStack4; + _signalFunctionNameStack4 = NULL; } void mcx_signal_handler_enable(void) { diff --git a/src/util/win/signals.c b/src/util/win/signals.c index f6c83ec..156b3b5 100644 --- a/src/util/win/signals.c +++ b/src/util/win/signals.c @@ -24,6 +24,8 @@ __declspec( thread ) static const char * _signalThreadName = NULL; __declspec( thread ) static const char * _signalFunctionName = NULL; __declspec( thread ) static const char * _signalFunctionNameStack1 = NULL; __declspec( thread ) static const char * _signalFunctionNameStack2 = NULL; +__declspec( thread ) static const char * _signalFunctionNameStack3 = NULL; +__declspec( thread ) static const char * _signalFunctionNameStack4 = NULL; #ifdef __cplusplus extern "C" { @@ -121,11 +123,13 @@ void mcx_signal_handler_unset_name(void) { void mcx_signal_handler_set_function(const char * functionName) { #if defined(MCX_DEBUG) - if (_signalFunctionNameStack2 != NULL) { + if (_signalFunctionNameStack4 != NULL) { mcx_log(LOG_ERROR, "Signal handler function callstack overflow!"); exit(1); // I guess there is a better way to handle this } #endif + _signalFunctionNameStack4 = _signalFunctionNameStack3; + _signalFunctionNameStack3 = _signalFunctionNameStack2; _signalFunctionNameStack2 = _signalFunctionNameStack1; _signalFunctionNameStack1 = _signalFunctionName; _signalFunctionName = functionName; @@ -139,7 +143,9 @@ void mcx_signal_handler_unset_function(void) { #endif _signalFunctionName = _signalFunctionNameStack1; _signalFunctionNameStack1 = _signalFunctionNameStack2; - _signalFunctionNameStack2 = NULL; + _signalFunctionNameStack2 = _signalFunctionNameStack3; + _signalFunctionNameStack3 = _signalFunctionNameStack4; + _signalFunctionNameStack4 = NULL; } void mcx_signal_handler_enable(void) { From 73dbc2167575039c024746c1a65c9255caa7d1e7 Mon Sep 17 00:00:00 2001 From: Klaus Schuch Date: Thu, 7 Apr 2022 22:23:27 +0200 Subject: [PATCH 15/16] signals: Remove individual fmu set/get calls --- src/fmu/common_fmu2.c | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/src/fmu/common_fmu2.c b/src/fmu/common_fmu2.c index 27c75b2..dd20a66 100644 --- a/src/fmu/common_fmu2.c +++ b/src/fmu/common_fmu2.c @@ -637,9 +637,7 @@ McxStatus Fmu2SetVariable(Fmu2CommonStruct * fmu, Fmu2Value * fmuVal) { { fmi2_value_reference_t vr[] = {fmuVal->data->vr.scalar}; - mcx_signal_handler_set_function("fmi2_import_set_real"); status = fmi2_import_set_real(fmu->fmiImport, vr, 1, (const fmi2_real_t *) ChannelValueReference(chVal)); - mcx_signal_handler_unset_function(); MCX_DEBUG_LOG("Set %s(%d)=%f", fmuVal->name, vr[0], *(double*)ChannelValueReference(chVal)); @@ -649,9 +647,7 @@ McxStatus Fmu2SetVariable(Fmu2CommonStruct * fmu, Fmu2Value * fmuVal) { { fmi2_value_reference_t vr[] = { fmuVal->data->vr.scalar }; - mcx_signal_handler_set_function("fmi2_import_set_integer"); status = fmi2_import_set_integer(fmu->fmiImport, vr, 1, (const fmi2_integer_t *) ChannelValueReference(chVal)); - mcx_signal_handler_unset_function(); MCX_DEBUG_LOG("Set %s(%d)=%d", fmuVal->name, vr[0], *(int*)ChannelValueReference(chVal)); @@ -661,9 +657,7 @@ McxStatus Fmu2SetVariable(Fmu2CommonStruct * fmu, Fmu2Value * fmuVal) { { fmi2_value_reference_t vr[] = { fmuVal->data->vr.scalar }; - mcx_signal_handler_set_function("fmi2_import_set_boolean"); status = fmi2_import_set_boolean(fmu->fmiImport, vr, 1, (const fmi2_boolean_t *) ChannelValueReference(chVal)); - mcx_signal_handler_unset_function(); break; } @@ -671,9 +665,7 @@ McxStatus Fmu2SetVariable(Fmu2CommonStruct * fmu, Fmu2Value * fmuVal) { { fmi2_value_reference_t vr[] = { fmuVal->data->vr.scalar }; - mcx_signal_handler_set_function("fmi2_import_set_string"); status = fmi2_import_set_string(fmu->fmiImport, vr, 1, (fmi2_string_t *) ChannelValueReference(chVal)); - mcx_signal_handler_unset_function(); break; } @@ -692,9 +684,7 @@ McxStatus Fmu2SetVariable(Fmu2CommonStruct * fmu, Fmu2Value * fmuVal) { , (fmi2_integer_t) binary->len }; - mcx_signal_handler_set_function("fmi2_import_set_integer"); status = fmi2_import_set_integer(fmu->fmiImport, vrs, 3, vals); - mcx_signal_handler_unset_function(); break; } @@ -751,9 +741,7 @@ McxStatus Fmu2GetVariable(Fmu2CommonStruct * fmu, Fmu2Value * fmuVal) { { fmi2_value_reference_t vr[] = { fmuVal->data->vr.scalar }; - mcx_signal_handler_set_function("fmi2_import_get_real"); status = fmi2_import_get_real(fmu->fmiImport, vr, 1, (fmi2_real_t *) ChannelValueReference(chVal)); - mcx_signal_handler_unset_function(); MCX_DEBUG_LOG("Get %s(%d)=%f", fmuVal->name, vr[0], *(double*)ChannelValueReference(chVal)); @@ -763,9 +751,7 @@ McxStatus Fmu2GetVariable(Fmu2CommonStruct * fmu, Fmu2Value * fmuVal) { { fmi2_value_reference_t vr[] = { fmuVal->data->vr.scalar }; - mcx_signal_handler_set_function("fmi2_import_get_integer"); status = fmi2_import_get_integer(fmu->fmiImport, vr, 1, (fmi2_integer_t *) ChannelValueReference(chVal)); - mcx_signal_handler_unset_function(); break; } @@ -773,9 +759,7 @@ McxStatus Fmu2GetVariable(Fmu2CommonStruct * fmu, Fmu2Value * fmuVal) { { fmi2_value_reference_t vr[] = { fmuVal->data->vr.scalar }; - mcx_signal_handler_set_function("fmi2_import_get_boolean"); status = fmi2_import_get_boolean(fmu->fmiImport, vr, 1, (fmi2_boolean_t *) ChannelValueReference(chVal)); - mcx_signal_handler_unset_function(); break; } @@ -785,9 +769,7 @@ McxStatus Fmu2GetVariable(Fmu2CommonStruct * fmu, Fmu2Value * fmuVal) { char * buffer = NULL; - mcx_signal_handler_set_function("fmi2_import_get_string"); status = fmi2_import_get_string(fmu->fmiImport, vr, 1, (fmi2_string_t *) &buffer); - mcx_signal_handler_unset_function(); ChannelValueSetFromReference(chVal, &buffer); break; @@ -804,12 +786,10 @@ McxStatus Fmu2GetVariable(Fmu2CommonStruct * fmu, Fmu2Value * fmuVal) { binary_string binary; - mcx_signal_handler_set_function("fmi2_import_get_integer"); status = fmi2_import_get_integer(fmu->fmiImport, vrs, 3, vs); - mcx_signal_handler_unset_function(); - binary.len = vs[2]; - binary.data = (char *) ((((long long)vs[1] & 0xffffffff) << 32) | (vs[0] & 0xffffffff)); + binary.len = vs[2]; + binary.data = (char *) ((((long long)vs[1] & 0xffffffff) << 32) | (vs[0] & 0xffffffff)); ChannelValueSetFromReference(chVal, &binary); From 98c143101b6ed4575b93f8ad0c3688efe7de24e4 Mon Sep 17 00:00:00 2001 From: Klaus Schuch Date: Thu, 7 Apr 2022 22:28:18 +0200 Subject: [PATCH 16/16] signals: Add fmi batch functions --- src/fmu/common_fmu1.c | 11 +++++++++++ src/fmu/common_fmu2.c | 10 ++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/fmu/common_fmu1.c b/src/fmu/common_fmu1.c index 446599d..dc72d00 100644 --- a/src/fmu/common_fmu1.c +++ b/src/fmu/common_fmu1.c @@ -15,6 +15,7 @@ #include "reader/model/parameters/ParameterInput.h" #include "util/string.h" +#include "util/signals.h" #include "fmilib.h" @@ -601,14 +602,19 @@ McxStatus Fmu1SetVariableArray(Fmu1CommonStruct * fmu, ObjectContainer * vals) { size_t i = 0; size_t numVars = vals->Size(vals); + mcx_signal_handler_set_this_function(); + for (i = 0; i < numVars; i++) { Fmu1Value * fmuVal = (Fmu1Value *) vals->At(vals, i); if (RETURN_ERROR == Fmu1SetVariable(fmu, fmuVal)) { + mcx_signal_handler_unset_function(); return RETURN_ERROR; } } + mcx_signal_handler_unset_function(); + return RETURN_OK; } @@ -672,15 +678,20 @@ McxStatus Fmu1GetVariableArray(Fmu1CommonStruct * fmu, ObjectContainer * vals) { size_t i = 0; size_t numVars = vals->Size(vals); + mcx_signal_handler_set_this_function(); + for (i = 0; i < numVars; i++) { McxStatus retVal = RETURN_OK; Fmu1Value * fmuVal = (Fmu1Value *) vals->At(vals, i); retVal = Fmu1GetVariable(fmu, fmuVal); if (RETURN_ERROR == retVal) { + mcx_signal_handler_unset_function(); return RETURN_ERROR; } } + mcx_signal_handler_unset_function(); + return RETURN_OK; } diff --git a/src/fmu/common_fmu2.c b/src/fmu/common_fmu2.c index dd20a66..2aaf9d7 100644 --- a/src/fmu/common_fmu2.c +++ b/src/fmu/common_fmu2.c @@ -716,15 +716,20 @@ McxStatus Fmu2SetVariableArray(Fmu2CommonStruct * fmu, ObjectContainer * vals) { McxStatus retVal = RETURN_OK; + mcx_signal_handler_set_this_function(); + for (i = 0; i < numVars; i++) { Fmu2Value * const fmuVal = (Fmu2Value *) vals->At(vals, i); retVal = Fmu2SetVariable(fmu, fmuVal); if (RETURN_ERROR == retVal) { + mcx_signal_handler_unset_function(); return RETURN_ERROR; } } + mcx_signal_handler_unset_function(); + return RETURN_OK; } @@ -823,16 +828,21 @@ McxStatus Fmu2GetVariableArray(Fmu2CommonStruct * fmu, ObjectContainer * vals) { McxStatus retVal = RETURN_OK; + mcx_signal_handler_set_this_function(); + for (i = 0; i < numVars; i++) { Fmu2Value * const fmuVal = (Fmu2Value *) vals->At(vals, i); retVal = Fmu2GetVariable(fmu, fmuVal); if (RETURN_ERROR == retVal) { mcx_log(LOG_ERROR, "FMU: Getting of variable array failed at element %u", i); + mcx_signal_handler_unset_function(); return RETURN_ERROR; } } + mcx_signal_handler_unset_function(); + return RETURN_OK; }