summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/dlt_user.c94
-rw-r--r--src/tests/dlt-test-fork-handler.c22
2 files changed, 74 insertions, 42 deletions
diff --git a/src/lib/dlt_user.c b/src/lib/dlt_user.c
index d45bb91..66ffd0b 100644
--- a/src/lib/dlt_user.c
+++ b/src/lib/dlt_user.c
@@ -95,9 +95,8 @@ static pthread_t dlt_receiverthread_handle;
/* calling dlt_user_atexit_handler() second time fails with error message */
static int atexit_registered = 0;
-/* calling atfork_handler() only once */
-static int atfork_registered = 0;
-
+/* used to disallow DLT usage in fork() child */
+static int g_dlt_is_child = 0;
/* Segmented Network Trace */
#define DLT_MAX_TRACE_SEGMENT_SIZE 1024
@@ -174,8 +173,6 @@ static DltReturnValue dlt_user_log_out_error_handling(void *ptr1,
static int dlt_start_threads();
static void dlt_stop_threads();
-static void dlt_fork_pre_fork_handler();
-static void dlt_fork_parent_fork_handler();
static void dlt_fork_child_fork_handler();
@@ -431,10 +428,7 @@ DltReturnValue dlt_init(void)
}
/* prepare for fork() call */
- if (atfork_registered == 0) {
- atfork_registered = 1;
- pthread_atfork(&dlt_fork_pre_fork_handler, &dlt_fork_parent_fork_handler, &dlt_fork_child_fork_handler);
- }
+ pthread_atfork(NULL, NULL, &dlt_fork_child_fork_handler);
return DLT_RETURN_OK;
}
@@ -710,6 +704,11 @@ DltReturnValue dlt_init_common(void)
void dlt_user_atexit_handler(void)
{
+ /* parent will do clean-up */
+ if (g_dlt_is_child) {
+ return;
+ }
+
if (!dlt_user_initialised) {
dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
/* close file */
@@ -950,6 +949,10 @@ DltReturnValue dlt_register_app(const char *appid, const char *description)
{
DltReturnValue ret = DLT_RETURN_OK;
+ /* forbid dlt usage in child after fork */
+ if (g_dlt_is_child)
+ return DLT_RETURN_ERROR;
+
if (!dlt_user_initialised) {
if (dlt_init() < 0) {
dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
@@ -1025,6 +1028,10 @@ DltReturnValue dlt_register_context(DltContext *handle, const char *contextid, c
if (handle == NULL)
return DLT_RETURN_WRONG_PARAMETER;
+ /* forbid dlt usage in child after fork */
+ if (g_dlt_is_child)
+ return DLT_RETURN_ERROR;
+
if (!dlt_user_initialised) {
if (dlt_init() < 0) {
dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
@@ -1059,6 +1066,10 @@ DltReturnValue dlt_register_context_ll_ts_llccb(DltContext *handle,
if ((handle == NULL) || (contextid == NULL) || (contextid[0] == '\0'))
return DLT_RETURN_WRONG_PARAMETER;
+ /* forbid dlt usage in child after fork */
+ if (g_dlt_is_child)
+ return DLT_RETURN_ERROR;
+
if ((loglevel < DLT_USER_LOG_LEVEL_NOT_SET) || (loglevel >= DLT_LOG_MAX)) {
dlt_vlog(LOG_ERR, "Loglevel %d is outside valid range", loglevel);
return DLT_RETURN_WRONG_PARAMETER;
@@ -1264,6 +1275,10 @@ DltReturnValue dlt_register_context_llccb(DltContext *handle,
if ((handle == NULL) || (contextid == NULL) || (contextid[0] == '\0'))
return DLT_RETURN_WRONG_PARAMETER;
+ /* forbid dlt usage in child after fork */
+ if (g_dlt_is_child)
+ return DLT_RETURN_ERROR;
+
if (!dlt_user_initialised) {
if (dlt_init() < 0) {
dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
@@ -1283,6 +1298,10 @@ DltReturnValue dlt_unregister_app(void)
{
DltReturnValue ret = DLT_RETURN_OK;
+ /* forbid dlt usage in child after fork */
+ if (g_dlt_is_child)
+ return DLT_RETURN_ERROR;
+
if (!dlt_user_initialised) {
dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
return DLT_RETURN_ERROR;
@@ -1310,6 +1329,10 @@ DltReturnValue dlt_unregister_app_flush_buffered_logs(void)
{
DltReturnValue ret = DLT_RETURN_OK;
+ /* forbid dlt usage in child after fork */
+ if (g_dlt_is_child)
+ return DLT_RETURN_ERROR;
+
if (!dlt_user_initialised) {
dlt_vlog(LOG_ERR, "%s dlt_user_initialised false\n", __func__);
return DLT_RETURN_ERROR;
@@ -1329,6 +1352,10 @@ DltReturnValue dlt_unregister_context(DltContext *handle)
DltContextData log;
DltReturnValue ret = DLT_RETURN_OK;
+ /* forbid dlt usage in child after fork */
+ if (g_dlt_is_child)
+ return DLT_RETURN_ERROR;
+
log.handle = NULL;
log.context_description = NULL;
@@ -1383,6 +1410,10 @@ DltReturnValue dlt_set_application_ll_ts_limit(DltLogLevelType loglevel, DltTrac
{
uint32_t i;
+ /* forbid dlt usage in child after fork */
+ if (g_dlt_is_child)
+ return DLT_RETURN_ERROR;
+
if ((loglevel < DLT_USER_LOG_LEVEL_NOT_SET) || (loglevel >= DLT_LOG_MAX)) {
dlt_vlog(LOG_ERR, "Loglevel %d is outside valid range", loglevel);
return DLT_RETURN_WRONG_PARAMETER;
@@ -1451,6 +1482,10 @@ int dlt_get_log_state()
DltReturnValue dlt_set_log_mode(DltUserLogMode mode)
{
+ /* forbid dlt usage in child after fork */
+ if (g_dlt_is_child)
+ return DLT_RETURN_ERROR;
+
if ((mode < DLT_USER_MODE_UNDEFINED) || (mode >= DLT_USER_MODE_MAX)) {
dlt_vlog(LOG_ERR, "User log mode %d is outside valid range", mode);
return DLT_RETURN_WRONG_PARAMETER;
@@ -1468,6 +1503,10 @@ DltReturnValue dlt_set_log_mode(DltUserLogMode mode)
int dlt_set_resend_timeout_atexit(uint32_t timeout_in_milliseconds)
{
+ /* forbid dlt usage in child after fork */
+ if (g_dlt_is_child)
+ return DLT_RETURN_ERROR;
+
if (dlt_user_initialised == 0) {
if (dlt_init() < 0)
return -1;
@@ -1486,6 +1525,10 @@ DltReturnValue dlt_forward_msg(void *msgdata, size_t size)
if ((msgdata == NULL) || (size == 0))
return DLT_RETURN_WRONG_PARAMETER;
+ /* forbid dlt usage in child after fork */
+ if (g_dlt_is_child)
+ return DLT_RETURN_ERROR;
+
if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG) < DLT_RETURN_OK)
/* Type of internal user message; same value for Trace messages */
return DLT_RETURN_ERROR;
@@ -1598,6 +1641,10 @@ DltReturnValue dlt_user_log_write_start_id(DltContext *handle,
if ((handle == NULL) || (log == NULL))
return DLT_RETURN_WRONG_PARAMETER;
+ /* forbid dlt usage in child after fork */
+ if (g_dlt_is_child)
+ return DLT_RETURN_ERROR;
+
/* check log levels */
ret = dlt_user_is_logLevel_enabled(handle, loglevel);
@@ -4681,35 +4728,10 @@ void dlt_stop_threads()
}
}
-static void dlt_fork_pre_fork_handler()
-{
- dlt_stop_threads();
-}
-
-static void dlt_fork_parent_fork_handler()
-{
- if (dlt_user_initialised) {
- if (dlt_start_threads() < 0) {
- snprintf(str, DLT_USER_BUFFER_LENGTH,
- "Logging disabled, failed re-start thread after fork(pid=%i)!\n",
- getpid());
- dlt_log(LOG_WARNING, str);
- /* cleanup is the only thing we can do here */
- dlt_log_free();
- dlt_free();
- }
- }
-}
-
static void dlt_fork_child_fork_handler()
{
- if (dlt_user_initialised) {
- /* don't start anything else but cleanup everything and avoid blow-out of buffers*/
- dlt_user.dlt_log_handle = -1;
- dlt_log_free();
- dlt_free();
- /* the only thing that remains is the atexit-handler */
- }
+ g_dlt_is_child = 1;
+ dlt_user_initialised = false;
}
DltReturnValue dlt_user_log_out_error_handling(void *ptr1, size_t len1, void *ptr2, size_t len2, void *ptr3,
diff --git a/src/tests/dlt-test-fork-handler.c b/src/tests/dlt-test-fork-handler.c
index 4bd3321..118753b 100644
--- a/src/tests/dlt-test-fork-handler.c
+++ b/src/tests/dlt-test-fork-handler.c
@@ -25,6 +25,8 @@
*/
#include <unistd.h> /* for fork() */
+#include <time.h>
+#include <errno.h>
#include "dlt.h"
@@ -34,23 +36,31 @@
int main()
{
DltContext mainContext;
+ struct timespec timeout, r;
+
+ timeout.tv_sec = 0;
+ timeout.tv_nsec = 200000000L;
DLT_REGISTER_APP("PRNT", "Parent application");
DLT_REGISTER_CONTEXT(mainContext, "CTXP", "Parent context");
DLT_LOG(mainContext, DLT_LOG_WARN, DLT_STRING("First message before fork"));
- usleep(200000);
+ nanosleep(&timeout, &r);
pid_t pid = fork();
-
if (pid == 0) { /* child process */
/* this message should not be visible */
- /* DLT_LOG(mainContext, DLT_LOG_WARN, DLT_STRING("Child's first message after fork, pid: "), DLT_INT32(getpid())); */
- /* unfortunately, this message does arrive, I assume because it still has (locally) valid data ... */
+ DLT_LOG(mainContext, DLT_LOG_WARN, DLT_STRING("Child's first message after fork, pid: "), DLT_INT32(getpid()));
+ /* this will not register CHLD application */
DLT_REGISTER_APP("CHLD", "Child application");
+ /* this will not register CTXC context */
DLT_REGISTER_CONTEXT(mainContext, "CTXC", "Child context");
+ /* this will not log a message */
DLT_LOG(mainContext, DLT_LOG_WARN, DLT_STRING("Child's second message after fork, pid: "), DLT_INT32(getpid()));
- usleep(400000);
+ nanosleep(&timeout, &r);
+ if (execlp("dlt-example-user", "dlt-example-user", "-n 1",
+ "you should see this message", NULL))
+ return errno;
}
else if (pid == -1) /* error in fork */
{
@@ -58,7 +68,7 @@ int main()
}
else { /* parent */
DLT_LOG(mainContext, DLT_LOG_WARN, DLT_STRING("Parent's first message after fork, pid: "), DLT_INT32(getpid()));
- usleep(500000);
+ nanosleep(&timeout, &r);
}
DLT_UNREGISTER_APP()