} else if (log.type == APP_MSG_TARGET_BINS) {
_process_target_bins((char *)data_buf, data_size);
} else if (log.type == APP_MSG_STOP) {
- /* Send acknowlege message to manager */
- printLog(&log, APP_MSG_STOP);
/* Do leaks check if LSan is enabled. */
lsan_do_leak_check();
+ /* Send acknowlege message to manager */
+ printLog(&log, APP_MSG_STOP);
+
application_exit();
break;
} else if (log.type == APP_MSG_STOP_WITHOUT_KILL) {
- /* Send acknowlege message to manager */
- printLog(&log, APP_MSG_STOP);
/* Do leaks check if LSan is enabled. */
lsan_do_leak_check();
+ /* Send acknowlege message to manager */
+ printLog(&log, APP_MSG_STOP);
+
_uninit_();
break;
} else if(log.type == APP_MSG_GET_UI_HIERARCHY) {
#include <stdio.h>
#include <string.h>
+#include <ulimit.h>
#include "lsan_open.h"
#include "binproto.h"
#include "daprobe.h"
#include "dahelper.h"
+#include "file_buffer.h"
#include "lsan/lsan_interface.h"
static void *liblsan_handle;
typedef const void *(*lsan_const_void_star_fun)();
typedef struct LeakedObject LeakedObject;
+
+static size_t pack_report_msg(char *p, const char *path, size_t *path_offset)
+{
+ char *msg_buf = p;
+
+ /* Pack common header. */
+ p = pack_int32(p, MSG_LSAN);
+ p = pack_int32(p, 0);
+ p = pack_timestamp(p);
+ p = pack_int32(p, 0);
+
+ /* Pack LSan specific data. */
+ p = pack_int32(p, LSAN_MSG_REPORT);
+ p = pack_int32(p, _getpid());
+ *path_offset = p - msg_buf + /* offset */
+ 4 + /* count args */
+ 1; /* size 's' */
+ p = pack_args(p, "s", path);
+
+ p = pack_int32(p, (uint32_t)0); /* internal call*/
+ p = pack_int64(p, (uintptr_t)0); /* caller addr */
+ SET_MSG_LEN();
+
+ return p - msg_buf;
+}
+
static void send_msg_to_host(const char *msg, lsan_status status)
{
char *msg_buf = (char *)malloc(MAX_LOCAL_BUF_SIZE);
msg_buf = NULL;
}
+static char *create_temp_path(const char *path)
+{
+ const char postfix[] = "_XXXXXX";
+ size_t len = strnlen(path, PATH_MAX);
+ char *new_path;
+
+ new_path = malloc(len + sizeof(postfix));
+ if (!new_path)
+ return NULL;
+
+ memcpy(new_path, path, len);
+ memcpy(new_path + len, postfix, sizeof(postfix));
+
+ return new_path;
+}
+
+static void send_report_to_manager(const char *path)
+{
+ struct file_buffer *fb;
+ void *buf, *p;
+ size_t buf_size, report_msg_size, path_offset;
+ char *report_msg, *new_path;
+
+ report_msg = malloc(MAX_LOCAL_BUF_SIZE);
+ if (!report_msg) {
+ PRINTERR("Cannot allocate report_msg buffer");
+ return;
+ }
+
+ fb = file_buffer_create(path); /* keep report in case of send problem */
+ if (!fb) {
+ PRINTERR("Cannot create file_buffer for '%s'", path);
+ goto free_report_msg;
+ }
+
+ new_path = create_temp_path(path);
+ if (!new_path) {
+ PRINTERR("Cannot create temp path");
+ goto destroy_fb;
+ }
+
+ /* pack common colums */
+ report_msg_size = pack_report_msg(report_msg, new_path, &path_offset);
+
+ /* format:
+ *
+ * | report_msg | path_offset | file_buffer |
+ * +------+------+-------------+------+------+
+ * | size | data | offset | size | data |
+ * | 4 | ... | 4 | 4 | ... |
+ */
+ buf_size = 4 + report_msg_size + /* report_msg */
+ 4 + /* path_offset */
+ 4 + fb->size; /* file_buffer */
+
+ buf = malloc(buf_size);
+ if (!buf) {
+ PRINTERR("Out of memory");
+ goto free_new_path;
+ }
+ p = buf;
+
+ /* pack report_msg */
+ p = pack_int32(p, report_msg_size);
+ p = pack_bin(p, report_msg, report_msg_size);
+
+ /* pack path_offset */
+ p = pack_int32(p, path_offset);
+
+ /* pack file_buffer */
+ p = pack_int32(p, fb->size);
+ p = pack_bin(p, fb->data, fb->size);
+
+ /* send lsan report to manager */
+ msg_send(APP_MSG_LSAN_REPORT, buf, buf_size);
+
+ free(buf);
+free_new_path:
+ free(new_path);
+destroy_fb:
+ file_buffer_destroy(fb);
+free_report_msg:
+ free(report_msg);
+}
+
static char *get_report_file_name() {
const char report_file_name_base[] = "/run/swap/tmp/lsan.log";
static char report_file_name[MAX_PATH_LENGTH];
}
fclose(report_file);
- send_msg_to_host(report_file_name, LSAN_MSG_REPORT);
+
+ send_report_to_manager(report_file_name);
}
static void report_leaked_chunks(int leaked_objects_num)