diff --git a/include/dlt/dlt_user.h.in b/include/dlt/dlt_user.h.in index 42254ace..5a0ec1e2 100644 --- a/include/dlt/dlt_user.h.in +++ b/include/dlt/dlt_user.h.in @@ -180,6 +180,9 @@ typedef struct /* Log Level changed callback */ void (*log_level_changed_callback)(char context_id[DLT_ID_SIZE], uint8_t log_level, uint8_t trace_status); +#ifdef DLT_TRACE_LOAD_CTRL_ENABLE + DltTraceLoadSettings *trace_load_settings; /**< trace load setting for the context */ +#endif } dlt_ll_ts_type; /** diff --git a/src/daemon/dlt-daemon.c b/src/daemon/dlt-daemon.c index 884338b5..f14ba027 100644 --- a/src/daemon/dlt-daemon.c +++ b/src/daemon/dlt-daemon.c @@ -1636,6 +1636,13 @@ int main(int argc, char *argv[]) dlt_gateway_deinit(&daemon_local.pGateway, daemon_local.flags.vflag); dlt_daemon_free(&daemon, daemon_local.flags.vflag); +#ifdef DLT_TRACE_LOAD_CTRL_ENABLE + if (daemon.preconfigured_trace_load_settings != NULL) { + free(daemon.preconfigured_trace_load_settings); + daemon.preconfigured_trace_load_settings = NULL; + } + pthread_rwlock_destroy(&trace_load_rw_lock); +#endif dlt_log(LOG_NOTICE, "Leaving DLT daemon\n"); @@ -3976,24 +3983,26 @@ bool trace_load_keep_message(DltDaemonApplication *app, app->apid, }; - DltTraceLoadSettings *trace_load_settings = - dlt_find_runtime_trace_load_settings( - app->trace_load_settings, app->trace_load_settings_count, - app->apid, msg->extendedheader->ctid); + DltDaemonContext *context = dlt_daemon_context_find( + daemon, + app->apid, + msg->extendedheader->ctid, + daemon->ecuid, + verbose); - if (trace_load_settings != NULL) { + if (context != NULL) { pthread_rwlock_wrlock(&trace_load_rw_lock); keep_message = dlt_check_trace_load( - trace_load_settings, mtin, msg->headerextra.tmsp, size, + context->trace_load_settings, mtin, msg->headerextra.tmsp, size, dlt_daemon_output_internal_msg, (void *)(¶ms)); pthread_rwlock_unlock(&trace_load_rw_lock); } else { dlt_vlog( LOG_ERR, - "Failed to lookup trace load limits for %s, " + "Failed to find context for app %.4s and context %.4s " "dropping message, likely app was not registered properly\n", - app->apid); + app->apid, msg->extendedheader->ctid); keep_message = false; } diff --git a/src/daemon/dlt_daemon_common.c b/src/daemon/dlt_daemon_common.c index f3aa277b..e933b22c 100644 --- a/src/daemon/dlt_daemon_common.c +++ b/src/daemon/dlt_daemon_common.c @@ -442,13 +442,6 @@ int dlt_daemon_free(DltDaemon *daemon, int verbose) free(daemon->app_id_log_level_settings); } #endif -#ifdef DLT_TRACE_LOAD_CTRL_ENABLE - if (daemon->preconfigured_trace_load_settings != NULL) { - free(daemon->preconfigured_trace_load_settings); - daemon->preconfigured_trace_load_settings = NULL; - } - pthread_rwlock_destroy(&trace_load_rw_lock); -#endif if (app_recv_buffer) free(app_recv_buffer); @@ -1133,6 +1126,9 @@ DltDaemonContext *dlt_daemon_context_add(DltDaemon *daemon, dlt_set_id(context->apid, apid); dlt_set_id(context->ctid, ctid); +#ifdef DLT_TRACE_LOAD_CTRL_ENABLE + context->trace_load_settings = NULL; +#endif application->num_contexts++; new_context = 1; @@ -1213,6 +1209,21 @@ DltDaemonContext *dlt_daemon_context_add(DltDaemon *daemon, context->log_level_pos = log_level_pos; context->user_handle = user_handle; +#ifdef DLT_TRACE_LOAD_CTRL_ENABLE + DltTraceLoadSettings* tl_settings = dlt_find_runtime_trace_load_settings( + application->trace_load_settings, + application->trace_load_settings_count, + application->apid, + context->ctid); + if (tl_settings == NULL) { + dlt_vlog(LOG_WARNING, "failed to find trace load settings for application %s context %s\n", + application->apid, context->ctid); + } else { + context->trace_load_settings = tl_settings; + } +#endif + + /* In case a context is loaded from runtime config file, * the user_handle is 0 and we mark that context as predefined. */ diff --git a/src/daemon/dlt_daemon_common.h b/src/daemon/dlt_daemon_common.h index fc91ee93..02470322 100644 --- a/src/daemon/dlt_daemon_common.h +++ b/src/daemon/dlt_daemon_common.h @@ -162,7 +162,10 @@ typedef struct int user_handle; /**< connection handle for connection to user application */ char *context_description; /**< context description */ int8_t storage_log_level; /**< log level set for offline logstorage */ - bool predefined; /**< set to true if this context is predefined by runtime configuration file */ + bool predefined; +#ifdef DLT_TRACE_LOAD_CTRL_ENABLE + DltTraceLoadSettings* trace_load_settings; /**< trace load setting for the context */ +#endif } DltDaemonContext; /* diff --git a/src/lib/dlt_user.c b/src/lib/dlt_user.c index a20cd781..f336f57d 100644 --- a/src/lib/dlt_user.c +++ b/src/lib/dlt_user.c @@ -229,7 +229,6 @@ static DltReturnValue dlt_unregister_app_util(bool force_sending_messages); static DltReturnValue dlt_user_output_internal_msg(DltLogLevelType loglevel, const char *text, void* params); DltTraceLoadSettings* trace_load_settings = NULL; uint32_t trace_load_settings_count = 0; -pthread_rwlock_t trace_load_rw_lock = PTHREAD_RWLOCK_INITIALIZER; #endif DltReturnValue dlt_user_check_library_version(const char *user_major_version, const char *user_minor_version) @@ -513,8 +512,8 @@ DltReturnValue dlt_init(void) #endif #ifdef DLT_TRACE_LOAD_CTRL_ENABLE - pthread_rwlock_wrlock(&trace_load_rw_lock); + DLT_SEM_LOCK(); trace_load_settings = malloc(sizeof(DltTraceLoadSettings)); if (trace_load_settings == NULL) { dlt_vlog(LOG_ERR, "Failed to allocate memory for trace load settings\n"); @@ -526,8 +525,7 @@ DltReturnValue dlt_init(void) trace_load_settings[0].hard_limit = DLT_TRACE_LOAD_CLIENT_HARD_LIMIT_DEFAULT; strncpy(trace_load_settings[0].apid, dlt_user.appID, DLT_ID_SIZE); trace_load_settings_count = 1; - - pthread_rwlock_unlock(&trace_load_rw_lock); + DLT_SEM_FREE(); #endif #ifdef DLT_LIB_USE_UNIX_SOCKET_IPC @@ -958,10 +956,6 @@ void dlt_user_atexit_handler(void) /* Cleanup */ /* Ignore return value */ dlt_free(); - -#ifdef DLT_TRACE_LOAD_CTRL_ENABLE - pthread_rwlock_destroy(&trace_load_rw_lock); -#endif } int dlt_user_atexit_blow_out_user_buffer(void) @@ -1543,8 +1537,20 @@ DltReturnValue dlt_register_context_ll_ts_llccb(DltContext *handle, dlt_user.dlt_ll_ts_num_entries++; - DLT_SEM_FREE(); +#ifdef DLT_TRACE_LOAD_CTRL_ENABLE + DltTraceLoadSettings* settings = dlt_find_runtime_trace_load_settings( + trace_load_settings, + trace_load_settings_count, + dlt_user.appID, + ctx_entry->contextID); + if (settings == NULL) { + dlt_vlog(LOG_WARNING, "No trace load settings found for %s.%s\n", dlt_user.appID, log.handle->contextID); + } else { + ctx_entry->trace_load_settings = settings; + } +#endif + DLT_SEM_FREE(); return dlt_user_log_send_register_context(&log); } @@ -4169,19 +4175,16 @@ DltReturnValue dlt_user_log_send_log(DltContextData *log, const int mtype, int * /* check trace load before output */ if (!sent_size) { - pthread_rwlock_wrlock(&trace_load_rw_lock); - DltTraceLoadSettings* settings = - dlt_find_runtime_trace_load_settings( - trace_load_settings, trace_load_settings_count, dlt_user.appID, log->handle->contextID); + DLT_SEM_LOCK(); const bool trace_load_in_limits = dlt_check_trace_load( - settings, + dlt_user.dlt_ll_ts[log->handle->log_level_pos].trace_load_settings, log->log_level, time_stamp, sizeof(DltUserHeader) + msg.headersize - sizeof(DltStorageHeader) + log->size, dlt_user_output_internal_msg, NULL); - pthread_rwlock_unlock(&trace_load_rw_lock); + DLT_SEM_FREE(); if (!trace_load_in_limits){ return DLT_RETURN_LOAD_EXCEEDED; } @@ -4403,7 +4406,6 @@ DltReturnValue dlt_user_log_send_register_context(DltContextData *log) usercontext.description_length); return DLT_RETURN_OK; - } DltReturnValue dlt_user_log_send_unregister_context(DltContextData *log) @@ -4882,18 +4884,17 @@ DltReturnValue dlt_user_log_check_user_message(void) trace_load_settings_user_messages = (DltUserControlMsgTraceSettingMsg *)(receiver->buf + sizeof(DltUserHeader) + sizeof(uint32_t)); - pthread_rwlock_wrlock(&trace_load_rw_lock); + DLT_SEM_LOCK(); // Remove the default created at startup if (trace_load_settings != NULL) { free(trace_load_settings); } - char msg[255]; + trace_load_settings_alloc_size = sizeof(DltTraceLoadSettings) * trace_load_settings_user_messages_count; trace_load_settings = malloc(trace_load_settings_alloc_size); if (trace_load_settings == NULL) { - pthread_rwlock_unlock(&trace_load_rw_lock); dlt_log(LOG_ERR, "Failed to allocate memory for trace load settings\n"); return DLT_RETURN_ERROR; } @@ -4904,29 +4905,33 @@ DltReturnValue dlt_user_log_check_user_message(void) trace_load_settings[i].soft_limit = trace_load_settings_user_messages[i].soft_limit; trace_load_settings[i].hard_limit = trace_load_settings_user_messages[i].hard_limit; } + trace_load_settings_count = trace_load_settings_user_messages_count; - pthread_rwlock_unlock(&trace_load_rw_lock); + for (i = 0; i < dlt_user.dlt_ll_ts_num_entries; ++i) { + dlt_ll_ts_type* ctx_entry = &dlt_user.dlt_ll_ts[i]; + ctx_entry->trace_load_settings = dlt_find_runtime_trace_load_settings( + trace_load_settings, trace_load_settings_count, dlt_user.appID, ctx_entry->contextID); + } + DLT_SEM_FREE(); - // must be sent with unlocked trace_load_rw_lock - for (i = 0; i < trace_load_settings_user_messages_count; i++) { - if (trace_load_settings[i].ctid[0] == '\0') { - snprintf( - msg, sizeof(msg), - "Received trace load settings: apid=%.4s, soft_limit=%u, hard_limit=%u\n", - trace_load_settings[i].apid, - trace_load_settings[i].soft_limit, - trace_load_settings[i].hard_limit); - } else { - snprintf( - msg, sizeof(msg), - "Received trace load settings: apid=%.4s, ctid=%.4s, soft_limit=%u, hard_limit=%u\n", - trace_load_settings[i].apid, - trace_load_settings[i].ctid, - trace_load_settings[i].soft_limit, - trace_load_settings[i].hard_limit); - } - dlt_user_output_internal_msg(DLT_LOG_INFO, msg, NULL); + // The log messages only can be produced safely when + // the trace load settings are set up fully. + char msg[255]; + if (trace_load_settings[i].ctid[0] == '\0') { + snprintf(msg, sizeof(msg), "Received trace load settings: apid=%.4s, soft_limit=%u, hard_limit=%u\n", + trace_load_settings[i].apid, + trace_load_settings[i].soft_limit, + trace_load_settings[i].hard_limit); + } else { + snprintf( + msg, sizeof(msg), + "Received trace load settings: apid=%.4s, ctid=%.4s, soft_limit=%u, hard_limit=%u\n", + trace_load_settings[i].apid, + trace_load_settings[i].ctid, + trace_load_settings[i].soft_limit, + trace_load_settings[i].hard_limit); } + dlt_user_output_internal_msg(DLT_LOG_INFO, msg, NULL); /* keep not read data in buffer */ if (dlt_receiver_remove(receiver, trace_load_settings_user_message_bytes_required) @@ -5349,9 +5354,6 @@ static void dlt_fork_child_fork_handler() g_dlt_is_child = 1; dlt_user_init_state = INIT_UNITIALIZED; dlt_user.dlt_log_handle = -1; -#ifdef DLT_TRACE_LOAD_CTRL_ENABLE - pthread_rwlock_unlock(&trace_load_rw_lock); -#endif } diff --git a/src/shared/dlt_common.c b/src/shared/dlt_common.c index 23a3def1..3abefbdb 100644 --- a/src/shared/dlt_common.c +++ b/src/shared/dlt_common.c @@ -4453,6 +4453,12 @@ bool dlt_check_trace_load( return true; } + if (tl_settings == NULL) + { + internal_dlt_log(DLT_LOG_ERROR, "tl_settings is NULL", internal_dlt_log_params); + return false; + } + if (size < 0) { dlt_vlog(LOG_ERR, "Invalid size: %d", size); diff --git a/tests/gtest_dlt_daemon.cpp b/tests/gtest_dlt_daemon.cpp index 3680ebae..e6993d10 100644 --- a/tests/gtest_dlt_daemon.cpp +++ b/tests/gtest_dlt_daemon.cpp @@ -385,6 +385,10 @@ TEST(t_trace_load_keep_message, normal) { int fd = 15; const char *desc = "HELLO_TEST"; + for (auto& app_id : app_ids) { + dlt_register_app(app_id, app_id); + } + const auto set_extended_header = [&daemon_local]() { daemon_local.msg.extendedheader = (DltExtendedHeader *)(daemon_local.msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)); @@ -402,6 +406,7 @@ TEST(t_trace_load_keep_message, normal) { const auto check_debug_and_trace_can_log = [&](DltDaemonApplication* app) { // messages for debug and verbose logs are never dropped set_extended_header_log_level(DLT_LOG_VERBOSE); + EXPECT_TRUE(trace_load_keep_message(app, app->trace_load_settings->hard_limit * 10, &daemon, &daemon_local, 0)); @@ -427,7 +432,7 @@ TEST(t_trace_load_keep_message, normal) { apps[0], apps[0]->trace_load_settings->soft_limit, &daemon, &daemon_local, 0)); set_extended_header(); - check_debug_and_trace_can_log(apps[0]); + memcpy(daemon_local.msg.extendedheader->apid, apps[0], DLT_ID_SIZE); // messages for apps that have not been registered should be dropped DltDaemonApplication app = {}; @@ -435,6 +440,8 @@ TEST(t_trace_load_keep_message, normal) { // Test if hard limit is reached for applications that only configure an application id // Meaning that the limit is shared between all contexts + dlt_daemon_context_add(&daemon, apps[0]->apid, "CT01", DLT_LOG_VERBOSE, 0, 0, 0, "", "ECU1", 0); + dlt_daemon_context_add(&daemon, apps[0]->apid, "CT02", DLT_LOG_VERBOSE, 0, 0, 0, "", "ECU1", 0); memcpy(daemon_local.msg.extendedheader->ctid, "CT01", DLT_ID_SIZE); log_until_hard_limit_reached(apps[0]); EXPECT_FALSE(trace_load_keep_message(apps[0], _trace_load_send_size, &daemon, &daemon_local, 0)); @@ -445,6 +452,11 @@ TEST(t_trace_load_keep_message, normal) { // APP1 has only three contexts, no app id memcpy(daemon_local.msg.extendedheader->ctid, "CT01", DLT_ID_SIZE); + memcpy(daemon_local.msg.extendedheader->apid, apps[1], DLT_ID_SIZE); + + dlt_daemon_context_add(&daemon, apps[1]->apid, "CT02", DLT_LOG_VERBOSE, 0, 0, 0, "", "ECU1", 0); + dlt_daemon_context_add(&daemon, apps[1]->apid, "CT02", DLT_LOG_VERBOSE, 0, 0, 0, "", "ECU1", 0); + log_until_hard_limit_reached(apps[1]); EXPECT_FALSE(trace_load_keep_message(apps[1], _trace_load_send_size, &daemon, &daemon_local, 0)); // CT01 has reached its limit, make sure CT02 still can log @@ -457,6 +469,10 @@ TEST(t_trace_load_keep_message, normal) { // APP2 has context and app id configured // Exhaust app limit first memcpy(daemon_local.msg.extendedheader->ctid, "CTXX", DLT_ID_SIZE); + memcpy(daemon_local.msg.extendedheader->apid, apps[2], DLT_ID_SIZE); + dlt_daemon_context_add(&daemon, apps[2]->apid, "CTXX", DLT_LOG_VERBOSE, 0, 0, 0, "", "ECU1", 0); + dlt_daemon_context_add(&daemon, apps[2]->apid, "CT01", DLT_LOG_VERBOSE, 0, 0, 0, "", "ECU1", 0); + log_until_hard_limit_reached(apps[2]); EXPECT_FALSE(trace_load_keep_message(apps[2], _trace_load_send_size, &daemon, &daemon_local, 0)); // Context logging should still be possible @@ -465,6 +481,9 @@ TEST(t_trace_load_keep_message, normal) { // Test not configured context memcpy(daemon_local.msg.extendedheader->ctid, "CTXX", DLT_ID_SIZE); + memcpy(daemon_local.msg.extendedheader->apid, apps[1], DLT_ID_SIZE); + dlt_daemon_context_add(&daemon, apps[1]->apid, "CTXX", DLT_LOG_VERBOSE, 0, 0, 0, "", "ECU1", 0); + EXPECT_EQ( trace_load_keep_message(apps[1], _trace_load_send_size, &daemon, &daemon_local, 0), DLT_TRACE_LOAD_DAEMON_HARD_LIMIT_DEFAULT != 0);