Skip to content

Commit c23d02d

Browse files
QNX:Injection for dlt-qnx-system (#495)
Introduce injection messages for dlt-qnx-system It helps to completely disable parsing slog2 entries in some unnecessary cases. dlt-qnx-system:potential leaks memory ctxt is allocated via new operator but there is no place delete later Use static variable instead of dynamic dlt-qnx-system:memory improvement It seems that in a rare case the stack memory could face unexpected issue Try to use heap memory instead of stack dlt-qnx-system:release memory in teardown The local stack variable to handle context map is handled incorrectly Solution is to apply an improvement with head memory and release memory properly qnxsystem: Correct arguments Signed-off-by: Saya Sugiura <[email protected]> Co-authored-by: Bui Nguyen Quoc Thanh <[email protected]>
1 parent 81ac18f commit c23d02d

File tree

3 files changed

+144
-61
lines changed

3 files changed

+144
-61
lines changed

doc/dlt-qnx-system.md

+17
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,20 @@ The description field is in the registration with libdlt.
100100
}
101101
}
102102
```
103+
104+
105+
### Runtime enable/disable slog2 adapter
106+
107+
The slog2 parser callback can be disabled and reenabled at runtime by using an injection.
108+
109+
| App ID | Context ID | Service ID | Data | Description |
110+
|--------|------------|------------|------|------------------------|
111+
| QSYM | QSYC | 0x1000 | 00 | Disable slog2 adapter |
112+
| QSYM | QSYC | 0x1000 | 01 | Reenable slog2 adapter |
113+
114+
### Example:
115+
116+
```bash
117+
dlt-control -e QNX -a QSYM -c QSYC -s 4096 -m "00" -u
118+
dlt-control -e QNX -a QSYM -c QSYC -s 4096 -m "01" -u
119+
```

src/dlt-qnx-system/dlt-qnx-slogger2-adapter.cpp

+28-9
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ extern DltContext dltQnxSystem;
4444
static DltContext dltQnxSlogger2Context;
4545

4646
extern DltQnxSystemThreads g_threads;
47+
48+
extern volatile bool g_inj_disable_slog2_cb;
49+
4750
static std::unordered_map<std::string, DltContext*> g_slog2file;
4851

4952
static void dlt_context_map_read(const char *json_filename)
@@ -137,8 +140,11 @@ static int sloggerinfo_callback(slog2_packet_info_t *info, void *payload, void *
137140
if (param == NULL)
138141
return -1;
139142

140-
if (info->data_type == SLOG2_TYPE_ONLINE)
141-
info->severity = SLOG2_INFO;
143+
if (g_inj_disable_slog2_cb == true) {
144+
DLT_LOG(dltQnxSystem, DLT_LOG_INFO,
145+
DLT_STRING("Disabling slog2 callback by injection request."));
146+
return -1;
147+
}
142148

143149
DltLogLevelType loglevel;
144150
switch (info->severity)
@@ -206,6 +212,7 @@ static int sloggerinfo_callback(slog2_packet_info_t *info, void *payload, void *
206212

207213
static void *slogger2_thread(void *v_conf)
208214
{
215+
int ret = -1;
209216
DltQnxSystemConfiguration *conf = (DltQnxSystemConfiguration *)v_conf;
210217

211218
if (v_conf == NULL)
@@ -215,18 +222,15 @@ static void *slogger2_thread(void *v_conf)
215222

216223
DLT_LOG(dltQnxSystem, DLT_LOG_DEBUG,
217224
DLT_STRING("dlt-qnx-slogger2-adapter, in thread."));
218-
DLT_REGISTER_CONTEXT(dltQnxSlogger2Context, conf->qnxslogger2.contextId,
219-
"SLOGGER2 Adapter");
220-
221-
dlt_context_map_read(CONFIGURATION_FILES_DIR "/dlt-slog2ctxt.json");
222225

223226
/**
224227
* Thread will block inside this function to get new log because
225228
* flag = SLOG2_PARSE_FLAGS_DYNAMIC
226229
*/
227-
int ret = slog2_parse_all(
230+
ret = slog2_parse_all(
228231
SLOG2_PARSE_FLAGS_DYNAMIC, /* live streaming of all buffers merged */
229232
NULL, NULL, &packet_info, sloggerinfo_callback, (void*) conf);
233+
230234
if (ret == -1) {
231235
DLT_LOG_CXX(dltQnxSlogger2Context, DLT_LOG_ERROR,
232236
"slog2_parse_all() returned error=", ret);
@@ -237,8 +241,18 @@ static void *slogger2_thread(void *v_conf)
237241

238242
DLT_UNREGISTER_CONTEXT(dltQnxSlogger2Context);
239243

240-
/* Send a signal to main thread to wake up sigwait */
241-
pthread_kill(g_threads.mainThread, SIGTERM);
244+
/* process should be shutdown if the callback was not manually disabled */
245+
if (g_inj_disable_slog2_cb == false) {
246+
for (auto& x: g_slog2file) {
247+
if(x.second != NULL) {
248+
delete(x.second);
249+
x.second = NULL;
250+
}
251+
}
252+
/* Send a signal to main thread to wake up sigwait */
253+
pthread_kill(g_threads.mainThread, SIGTERM);
254+
}
255+
242256
return reinterpret_cast<void*>(ret);
243257
}
244258

@@ -247,6 +261,11 @@ void start_qnx_slogger2(DltQnxSystemConfiguration *conf)
247261
static pthread_attr_t t_attr;
248262
static pthread_t pt;
249263

264+
DLT_REGISTER_CONTEXT(dltQnxSlogger2Context, conf->qnxslogger2.contextId,
265+
"SLOGGER2 Adapter");
266+
267+
dlt_context_map_read(CONFIGURATION_FILES_DIR "/dlt-slog2ctxt.json");
268+
250269
DLT_LOG_CXX(dltQnxSlogger2Context, DLT_LOG_DEBUG,
251270
"dlt-qnx-slogger2-adapter, start syslog");
252271
pthread_create(&pt, &t_attr, slogger2_thread, conf);

src/dlt-qnx-system/dlt-qnx-system.c

+99-52
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <sys/types.h>
2828
#include <fcntl.h>
2929
#include <err.h>
30+
#include <stdbool.h>
3031

3132
#include "dlt.h"
3233
#include "dlt-qnx-system.h"
@@ -36,18 +37,30 @@ DLT_DECLARE_CONTEXT(dltQnxSystem)
3637
/* Global variables */
3738
volatile DltQnxSystemThreads g_threads;
3839

40+
#define INJECTION_SLOG2_ADAPTER 4096
41+
42+
#define DATA_DISABLED "00"
43+
#define DATA_ENABLED "01"
44+
45+
volatile bool g_inj_disable_slog2_cb = false;
46+
3947
/* Function prototype */
4048
static void daemonize();
41-
static void start_threads(DltQnxSystemConfiguration *config);
49+
static void start_threads();
4250
static void join_threads();
43-
static int read_configuration_file(DltQnxSystemConfiguration *config,
44-
const char *file_name);
51+
static int read_configuration_file(const char *file_name);
4552
static int read_command_line(DltQnxSystemCliOptions *options, int argc, char *argv[]);
4653

54+
static int dlt_injection_cb(uint32_t service_id, void *data, uint32_t length);
55+
56+
static DltQnxSystemConfiguration *g_dlt_qnx_conf = NULL;
57+
static void init_configuration();
58+
static void clean_up();
59+
60+
4761
int main(int argc, char* argv[])
4862
{
4963
DltQnxSystemCliOptions options;
50-
DltQnxSystemConfiguration config;
5164
int sigNo = 0;
5265
int ret = 0;
5366
sigset_t mask;
@@ -59,7 +72,7 @@ int main(int argc, char* argv[])
5972
return -1;
6073
}
6174

62-
if (read_configuration_file(&config, options.configurationFileName) < 0)
75+
if (read_configuration_file(options.configurationFileName) < 0)
6376
{
6477
fprintf(stderr, "Failed to read configuration file!\n");
6578
return -1;
@@ -82,17 +95,19 @@ int main(int argc, char* argv[])
8295
return -1;
8396
}
8497

85-
DLT_REGISTER_APP(config.applicationId, "DLT QNX System");
86-
DLT_REGISTER_CONTEXT(dltQnxSystem, config.applicationContextId,
98+
DLT_REGISTER_APP(g_dlt_qnx_conf->applicationId, "DLT QNX System");
99+
DLT_REGISTER_CONTEXT(dltQnxSystem, g_dlt_qnx_conf->applicationContextId,
87100
"Context of main dlt qnx system manager");
101+
dlt_register_injection_callback(&dltQnxSystem,
102+
INJECTION_SLOG2_ADAPTER, dlt_injection_cb);
88103

89104
DLT_LOG(dltQnxSystem, DLT_LOG_DEBUG,
90105
DLT_STRING("Setting signals wait for abnormal exit"));
91106

92107
g_threads.mainThread = pthread_self();
93108

94109
DLT_LOG(dltQnxSystem, DLT_LOG_DEBUG, DLT_STRING("Launching threads."));
95-
start_threads(&config);
110+
start_threads();
96111

97112
ret = sigwait(&mask, &sigNo);
98113

@@ -114,6 +129,7 @@ int main(int argc, char* argv[])
114129
DLT_STRING(strsignal(sigNo)));
115130

116131
DLT_UNREGISTER_APP_FLUSH_BUFFERED_LOGS();
132+
clean_up();
117133
return 0;
118134

119135
}
@@ -193,23 +209,22 @@ static int read_command_line(DltQnxSystemCliOptions *options, int argc, char *ar
193209
/**
194210
* Initialize configuration to default values.
195211
*/
196-
static void init_configuration(DltQnxSystemConfiguration *config)
212+
static void init_configuration()
197213
{
214+
g_dlt_qnx_conf = calloc(1, sizeof(DltQnxSystemConfiguration));
198215
/* Common */
199-
config->applicationId = "QSYM";
200-
config->applicationContextId = "QSYC";
201-
216+
g_dlt_qnx_conf->applicationId = strdup("QSYM");
217+
g_dlt_qnx_conf->applicationContextId = strdup("QSYC");
202218
/* Slogger2 */
203-
config->qnxslogger2.enable = 0;
204-
config->qnxslogger2.contextId = "QSLA";
205-
config->qnxslogger2.useOriginalTimestamp = 1;
219+
g_dlt_qnx_conf->qnxslogger2.enable = 0;
220+
g_dlt_qnx_conf->qnxslogger2.contextId = strdup("QSLA");
221+
g_dlt_qnx_conf->qnxslogger2.useOriginalTimestamp = 1;
206222
}
207223

208224
/**
209225
* Read options from the configuration file
210226
*/
211-
static int read_configuration_file(DltQnxSystemConfiguration *config,
212-
const char *file_name)
227+
static int read_configuration_file(const char *file_name)
213228
{
214229
FILE *file;
215230
char *line;
@@ -218,12 +233,16 @@ static int read_configuration_file(DltQnxSystemConfiguration *config,
218233
char *pch;
219234
int ret = 0;
220235

221-
init_configuration(config);
236+
init_configuration();
237+
if (g_dlt_qnx_conf == NULL) {
238+
fprintf(stderr,
239+
"dlt-qnx-system, could not allocate memory.\n");
240+
return -1;
241+
}
222242

223243
file = fopen(file_name, "r");
224244

225-
if (file == NULL)
226-
{
245+
if (file == NULL) {
227246
fprintf(stderr,
228247
"dlt-qnx-system, could not open configuration file.\n");
229248
return -1;
@@ -270,42 +289,34 @@ static int read_configuration_file(DltQnxSystemConfiguration *config,
270289
/* Common */
271290
if (strcmp(token, "ApplicationId") == 0)
272291
{
273-
config->applicationId = (char *)malloc(strlen(value) + 1);
274-
MALLOC_ASSERT(config->applicationId);
275-
/**
276-
* strcpy unritical here, because size matches exactly the
277-
* size to be copied
278-
*/
279-
strcpy(config->applicationId, value);
292+
if (g_dlt_qnx_conf->applicationId)
293+
free(g_dlt_qnx_conf->applicationId);
294+
g_dlt_qnx_conf->applicationId = strndup(value, DLT_ID_SIZE);
295+
MALLOC_ASSERT(g_dlt_qnx_conf->applicationId);
280296
}
281297
else if (strcmp(token, "ApplicationContextID") == 0)
282298
{
283-
config->applicationContextId = (char *)malloc(strlen(value) + 1);
284-
MALLOC_ASSERT(config->applicationContextId);
285-
/**
286-
* strcpy unritical here, because size matches exactly
287-
* the size to be copied
288-
*/
289-
strcpy(config->applicationContextId, value);
299+
if (g_dlt_qnx_conf->applicationContextId)
300+
free(g_dlt_qnx_conf->applicationContextId);
301+
g_dlt_qnx_conf->applicationContextId = strndup(value, DLT_ID_SIZE);
302+
MALLOC_ASSERT(g_dlt_qnx_conf->applicationContextId);
303+
strncpy(g_dlt_qnx_conf->applicationContextId, value, DLT_ID_SIZE);
290304
}
291305
/* Slogger2 */
292306
else if (strcmp(token, "QnxSlogger2Enable") == 0)
293307
{
294-
config->qnxslogger2.enable = atoi(value);
308+
g_dlt_qnx_conf->qnxslogger2.enable = atoi(value);
295309
}
296310
else if (strcmp(token, "QnxSlogger2ContextId") == 0)
297311
{
298-
config->qnxslogger2.contextId = (char *)malloc(strlen(value) + 1);
299-
MALLOC_ASSERT(config->qnxslogger2.contextId);
300-
/**
301-
* strcpy unritical here, because size matches exactly
302-
* the size to be copied
303-
*/
304-
strcpy(config->qnxslogger2.contextId, value);
312+
if (g_dlt_qnx_conf->qnxslogger2.contextId)
313+
free(g_dlt_qnx_conf->qnxslogger2.contextId);
314+
g_dlt_qnx_conf->qnxslogger2.contextId = strndup(value, DLT_ID_SIZE);
315+
MALLOC_ASSERT(g_dlt_qnx_conf->qnxslogger2.contextId);
305316
}
306317
else if (strcmp(token, "QnxSlogger2UseOriginalTimestamp") == 0)
307318
{
308-
config->qnxslogger2.useOriginalTimestamp = atoi(value);
319+
g_dlt_qnx_conf->qnxslogger2.useOriginalTimestamp = atoi(value);
309320
}
310321
else
311322
{
@@ -372,16 +383,10 @@ static void daemonize()
372383
signal(SIGTTIN, SIG_IGN);
373384
}
374385

375-
static void start_threads(DltQnxSystemConfiguration *config)
386+
static void start_threads()
376387
{
377388
int i = 0;
378389

379-
/* Check parameter */
380-
if (!config)
381-
{
382-
return;
383-
}
384-
385390
DLT_LOG(dltQnxSystem, DLT_LOG_DEBUG,
386391
DLT_STRING("dlt-qnx-system, start threads"));
387392

@@ -393,9 +398,9 @@ static void start_threads(DltQnxSystemConfiguration *config)
393398
g_threads.threads[i] = 0;
394399
}
395400

396-
if (config->qnxslogger2.enable)
401+
if (g_dlt_qnx_conf->qnxslogger2.enable)
397402
{
398-
start_qnx_slogger2(config);
403+
start_qnx_slogger2(g_dlt_qnx_conf);
399404
}
400405
}
401406

@@ -430,3 +435,45 @@ static void join_threads()
430435

431436
DLT_UNREGISTER_CONTEXT(dltQnxSystem);
432437
}
438+
439+
static int dlt_injection_cb(uint32_t service_id, void *data, uint32_t length)
440+
{
441+
(void) length;
442+
DLT_LOG(dltQnxSystem, DLT_LOG_INFO,
443+
DLT_STRING("Injection received:"),
444+
DLT_INT32(service_id));
445+
446+
if (service_id != INJECTION_SLOG2_ADAPTER)
447+
return -1;
448+
449+
if (0 == strncmp((char*) data, DATA_DISABLED, sizeof(DATA_DISABLED)-1))
450+
g_inj_disable_slog2_cb = true;
451+
else if (0 == strncmp((char*) data, DATA_ENABLED, sizeof(DATA_ENABLED)-1)) {
452+
if (g_inj_disable_slog2_cb == true) {
453+
g_inj_disable_slog2_cb = false;
454+
start_threads();
455+
}
456+
}
457+
458+
return 0;
459+
}
460+
461+
static void clean_up()
462+
{
463+
if (g_dlt_qnx_conf->applicationId) {
464+
free(g_dlt_qnx_conf->applicationId);
465+
g_dlt_qnx_conf->applicationId = NULL;
466+
}
467+
if (g_dlt_qnx_conf->applicationContextId) {
468+
free(g_dlt_qnx_conf->applicationContextId);
469+
g_dlt_qnx_conf->applicationContextId = NULL;
470+
}
471+
if (g_dlt_qnx_conf->qnxslogger2.contextId) {
472+
free(g_dlt_qnx_conf->qnxslogger2.contextId);
473+
g_dlt_qnx_conf->qnxslogger2.contextId = NULL;
474+
}
475+
if (g_dlt_qnx_conf) {
476+
free(g_dlt_qnx_conf);
477+
g_dlt_qnx_conf = NULL;
478+
}
479+
}

0 commit comments

Comments
 (0)