};
} muse_channel_info_t;
+typedef struct ms_trace {
+ int pss;
+ int diff;
+} ms_trace_t;
+
typedef struct muse_module {
muse_channel_info_t ch[MUSE_CHANNEL_MAX];
char recv_msg[MUSE_MSG_MAX_LENGTH + 1];
intptr_t handle;
gboolean is_created;
GMutex dispatch_lock;
+ ms_trace_t t;
} muse_module_t;
typedef struct muse_recv_data_head {
Name: mused
Summary: A multimedia daemon
-Version: 0.3.147
+Version: 0.3.148
Release: 0
Group: System/Libraries
License: Apache-2.0
#define MUSE_LOG "muse:logfile"
#define MUSE_LOCK "muse:lockfile"
#define MUSE_CHECK_CPU_MEMORY "muse:check_cpu_memory"
+#define MUSE_MEMORY_LEAK_THRESHOLD "muse:memory_leak_threshold"
#define MUSE_LOG_PERIOD "muse:log_period"
#define MUSE_WATCHDOG_MIN_TIMEOUT "muse:min_timeout"
#define MUSE_WATCHDOG_MAX_TIMEOUT "muse:max_timeout"
int host_cnt;
gboolean check_cpu_memory;
gboolean log_enabled;
+ int fd;
+ char *logfile;
char *lockfile;
int log_period;
int min_timeout;
int max_timeout;
int memory_threshold;
+ int memory_leak_threshold;
int cpu_threshold;
gboolean is_watch_external_storage_enabled;
char *gst_param_str[MUSE_PARAM_MAX];
char *ms_config_get_gst_preload_plugins(void);
char *ms_config_get_path(int idx);
char *ms_config_get_preloaded_value(int idx);
+char *ms_config_get_logfile(void);
+int ms_config_get_log_fd(void);
char *ms_config_get_lockfile(void);
gboolean ms_config_is_log_enabled(void);
void ms_config_remove_lockfile(void);
gboolean ms_config_is_check_cpu_memory(void);
+gboolean ms_config_is_memory_leak_detection_enabled(void);
+int ms_config_get_memory_leak_threshold(void);
int ms_config_get_log_period(void);
int ms_config_get_min_timeout(void);
int ms_config_get_max_timeout(void);
int host_idx;
char *hosts = NULL;
char *host = NULL;
- char *str = NULL;
char *ptr = NULL;
char *key = NULL;
char gst_param_key[MUSE_MSG_LEN_MAX];
goto out;
}
- str = _ms_config_get_str(conf->muse_dict, MUSE_LOG, NULL);
- if (str) {
- if (strncmp(str, MUSE_USE_LOG, strlen(MUSE_USE_LOG)) == 0)
- conf->log_enabled = TRUE;
- else
- conf->log_enabled = FALSE;
- free(str);
- } else {
- LOGE("[%s] get string error", MUSE_LOG);
+ conf->logfile = _ms_config_get_str(conf->muse_dict, MUSE_LOG, NULL);
+ if (conf->logfile)
+ conf->log_enabled = (strncmp(conf->logfile, MUSE_USE_LOG, strlen(MUSE_USE_LOG) == 0));
+ else
conf->log_enabled = FALSE;
- }
+
+ muse_core_remove_symlink(conf->logfile);
+ conf->fd = open(conf->logfile, O_CREAT | O_APPEND | O_WRONLY | O_NONBLOCK, 0644);
conf->lockfile = _ms_config_get_str(conf->muse_dict, MUSE_LOCK, NULL);
if (!conf->lockfile) {
conf->check_cpu_memory = (gboolean)_ms_config_get_int(conf->muse_dict, MUSE_CHECK_CPU_MEMORY, TRUE);
+ conf->memory_leak_threshold = _ms_config_get_int(conf->muse_dict, MUSE_MEMORY_LEAK_THRESHOLD, 0);
+
conf->log_period = _ms_config_get_int(conf->muse_dict, MUSE_LOG_PERIOD, DEFAULT_LOG_PERIOD);
conf->min_timeout = _ms_config_get_int(conf->muse_dict, MUSE_WATCHDOG_MIN_TIMEOUT, DEFAULT_WATCHDOG_MIN_TIMEOUT);
MUSE_FREE(conf->host[idx]);
}
+ MUSE_FREE(conf->logfile);
MUSE_FREE(conf->lockfile);
for (idx = 0; idx <= conf->gst_param_cnt; idx++)
return value;
}
+char *ms_config_get_logfile(void)
+{
+ ms_config_t *conf = _ms_config_get_instance();
+
+ muse_return_val_if_fail(conf, NULL);
+
+ return conf->logfile;
+}
+
+int ms_config_get_log_fd(void)
+{
+ ms_config_t *conf = _ms_config_get_instance();
+ muse_return_val_if_fail(conf, MUSE_ERR);
+
+ return conf->fd;
+}
+
char *ms_config_get_lockfile(void)
{
ms_config_t *conf = _ms_config_get_instance();
return conf->check_cpu_memory;
}
+gboolean ms_config_is_memory_leak_detection_enabled(void)
+{
+ ms_config_t *conf = _ms_config_get_instance();
+ muse_return_val_if_fail(conf, FALSE);
+
+ return (conf->memory_leak_threshold != 0);
+}
+
+int ms_config_get_memory_leak_threshold(void)
+{
+ ms_config_t *conf = _ms_config_get_instance();
+ muse_return_val_if_fail(conf, MUSE_ERR);
+
+ return conf->memory_leak_threshold;
+}
+
int ms_config_get_log_period(void)
{
ms_config_t *conf = _ms_config_get_instance();
#ifdef MUSE_USE_RM_READY
#include "mm_resource_manager.h"
#endif
+#include <execinfo.h>
static GMutex dllsym_table_lock;
static gboolean _ms_module_dispatch_timeout_callback(gpointer data);
static gboolean _ms_module_enable_dispatch_timeout_callback(int cmd, muse_module_h m);
static void _ms_module_set_loaded_dllsym(int idx, GModule *dllsym, gboolean value);
+static void _ms_module_write_name_time(int fd, int idx);
+static void _ms_module_backtrace(int fd);
+static void _ms_module_check_memory(muse_module_h m);
static gboolean _ms_module_dispatch_timeout_callback(gpointer data)
{
SECURE_LOGD("dll_handle: %p", module->dllsym);
}
+static void _ms_module_write_name_time(int fd, int idx)
+{
+ struct timespec tv;
+ char buf[MUSE_MSG_LEN_MAX] = {0};
+ char time_buf[MUSE_MSG_TIME_LEN] = {0};
+ char *name = ms_config_get_host_name(idx);
+
+ muse_core_get_cur_time(&tv, NULL);
+ muse_core_change_time_format((int)tv.tv_sec, time_buf);
+
+ snprintf(buf, MUSE_MSG_LEN_MAX, "%s %s", name, time_buf);
+
+ write(fd, buf, strlen(buf));
+ write(fd, "\n", 1);
+}
+
+static void _ms_module_backtrace(int fd)
+{
+ void *trace[MUSE_MSG_LEN];
+ Dl_info info;
+ int idx;
+ char *sym_addr = NULL, **s = NULL;
+
+ /* FIXME: Consider the performance and deadlock by non async-signal-safe function */
+ int sz = backtrace(trace, MUSE_MSG_LEN);
+ if (sz <= 0)
+ return;
+
+ s = backtrace_symbols(trace, sz);
+ if (!s)
+ return;
+
+ for (idx = 0; idx < sz; idx++) {
+ sym_addr = g_strstr_len(s[idx], strlen(s[idx]), "[0x");
+
+ memset(&info, 0, sizeof(info));
+
+ write(fd, s[idx], strlen(s[idx]));
+ if (sym_addr && dladdr((const void *)strtoul(sym_addr + 1, NULL, 16), &info) && info.dli_sname)
+ write(fd, info.dli_sname, strlen(info.dli_sname));
+ write(fd, "\n", 1);
+ }
+
+ free(s);
+}
+
+static void _ms_module_check_memory(muse_module_h m)
+{
+ int fd;
+
+ muse_return_if_fail(ms_get_instance());
+
+ int pss = ms_system_get_memory_usage(ms_get_instance()->pid);
+ int diff = pss - m->t.pss;
+ m->t.pss = pss;
+
+ if (diff > m->t.diff && diff > ms_config_get_memory_leak_threshold()) {
+ m->t.diff = diff;
+ fd = ms_config_get_log_fd();
+ if (fd == MUSE_ERR)
+ return;
+ _ms_module_write_name_time(fd, m->idx);
+ _ms_module_backtrace(fd);
+ }
+}
+
GModule *ms_module_open(int idx)
{
GModule *dllsym = NULL;
if (!rm_success)
LOGE("[%s] [%d] Failed to remove %d", ms_config_get_host_name(m->idx), api, id);
}
+
+ if (ms_config_is_memory_leak_detection_enabled())
+ _ms_module_check_memory(m);
} else {
LOGE("[%s] [%d] error - dispatcher", ms_config_get_host_name(m->idx), api);
ret = MUSE_ERR;