[minicoredumper] [PATCH 01/14] minicoredumper: Save command line arguments in cmd_parameters structure

Mateusz Moscicki m.moscicki2 at partner.samsung.com
Tue May 21 14:52:37 CEST 2019


Change-Id: I01baf48d743d76599a68c5a6a358092d0c24ef27
---
 src/minicoredumper/corestripper.c | 276 +++++++++++++++++++++++---------------
 src/minicoredumper/corestripper.h |  20 ++-
 2 files changed, 178 insertions(+), 118 deletions(-)

diff --git a/src/minicoredumper/corestripper.c b/src/minicoredumper/corestripper.c
index d96d1df..48fa4e5 100644
--- a/src/minicoredumper/corestripper.c
+++ b/src/minicoredumper/corestripper.c
@@ -379,7 +379,7 @@ static int get_task_list(struct dump_info *di)
 	di->tsks = NULL;
 	di->ntsks = 0;
 
-	snprintf(buf, sizeof(buf), "/proc/%d/task", di->pid);
+	snprintf(buf, sizeof(buf), "/proc/%d/task", di->cmd_params->pid);
 
 	d = opendir(buf);
 	if (!d)
@@ -573,7 +573,7 @@ static char *alloc_dst_dir(time_t timestamp, const char *base_dir,
 	return tmp_path;
 }
 
-static int init_di(struct dump_info *di, int argc, char *argv[])
+static int init_di(struct dump_info *di)
 {
 	const char *recept;
 	char *comm_base;
@@ -590,52 +590,22 @@ static int init_di(struct dump_info *di, int argc, char *argv[])
 	di->core_fd = -1;
 	di->fatcore_fd = -1;
 
-	di->pid = strtol(argv[1], &p, 10);
-	if (*p != 0)
-		return 1;
-
-	di->uid = strtol(argv[2], &p, 10);
-	if (*p != 0)
-		return 1;
+	di->cfg = init_config(di->cmd_params->cfg_path);
 
-	di->gid = strtol(argv[3], &p, 10);
-	if (*p != 0)
-		return 1;
-
-	di->signum = strtol(argv[4], &p, 10);
-	if (*p != 0)
-		return 1;
+	if (!di->cfg)
+		fatal("unable to init config");
 
-	di->timestamp = strtol(argv[5], &p, 10);
-	if (*p != 0)
-		return 1;
+	check_config(di->cfg);
 
-	di->hostname = argv[6];
-	if (!di->hostname)
-		return 1;
 
-	di->comm = alloc_comm(argv[7], di->pid);
+	di->comm = alloc_comm(di->cmd_params->exe_name, di->cmd_params->pid);
 	if (!di->comm)
-		return 1;
+		fatal("error while reading the comm file");
 
-	di->exe = alloc_exe(di->pid);
+	di->exe = alloc_exe(di->cmd_params->pid);
 	if (!di->exe)
-		return 1;
+		fatal("error while reading the exe file");
 
-	if (argc == 8) {
-		di->cfg = init_config(MCD_CONF_PATH
-				      "/minicoredumper.cfg.json");
-	} else if (argc == 9) {
-		info("using custom minicoredumper cfg: %s", argv[8]);
-		di->cfg = init_config(argv[8]);
-	} else {
-		fatal("wrong arg count, check /proc/sys/kernel/core_pattern");
-	}
-
-	if (!di->cfg)
-		fatal("unable to init config");
-
-	check_config(di->cfg);
 
 	info("comm: %s", di->comm);
 	info("exe: %s", di->exe);
@@ -661,9 +631,9 @@ static int init_di(struct dump_info *di, int argc, char *argv[])
 	if (get_task_list(di) != 0)
 		return 1;
 
-	if (di->signum != 0) {
+	if (di->cmd_params->signum != 0) {
 		if (asprintf(&tmp_path, "/core-%s-%d", comm_base,
-			     di->pid) == -1) {
+			     di->cmd_params->pid) == -1) {
 			return 1;
 		}
 
@@ -714,7 +684,7 @@ static int init_di(struct dump_info *di, int argc, char *argv[])
 		free(tmp_path);
 	}
 
-	if (asprintf(&tmp_path, "/proc/%i/mem", di->pid) == -1)
+	if (asprintf(&tmp_path, "/proc/%i/mem", di->cmd_params->pid) == -1)
 		return 1;
 
 	di->mem_fd = open(tmp_path, O_RDONLY);
@@ -752,8 +722,8 @@ static int init_log(struct dump_info *di)
 	fprintf(di->info_file, "Core Dump Log\n");
 	fprintf(di->info_file, "-------------\n");
 	fprintf(di->info_file, "Program: %s\n", di->exe);
-	fprintf(di->info_file, "PID: %i UID: %i GID: %i\n", di->pid,
-		di->uid, di->gid);
+	fprintf(di->info_file, "PID: %i UID: %i GID: %i\n", di->cmd_params->pid,
+		di->cmd_params->uid, di->cmd_params->gid);
 
 	return 0;
 }
@@ -2203,7 +2173,7 @@ static int dump_maps(struct dump_info *di, int get_only)
 		goto out_err;
 
 	/* open maps file */
-	snprintf(buf, MAPS_LINE_MAXSIZE, "/proc/%d/maps", di->pid);
+	snprintf(buf, MAPS_LINE_MAXSIZE, "/proc/%d/maps", di->cmd_params->pid);
 	f = fopen(buf, "r");
 	if (!f)
 		goto out_err;
@@ -2629,11 +2599,11 @@ static int dump_data_content_file(struct dump_info *di,
 	mkdir(tmp_path, 0700);
 
 	/* create dumps pid sub-directory */
-	snprintf(tmp_path, len, "%s/dumps/%i", di->dst_dir, di->pid);
+	snprintf(tmp_path, len, "%s/dumps/%i", di->dst_dir, di->cmd_params->pid);
 	mkdir(tmp_path, 0700);
 
 	/* open text file for output */
-	snprintf(tmp_path, len, "%s/dumps/%i/%s", di->dst_dir, di->pid,
+	snprintf(tmp_path, len, "%s/dumps/%i/%s", di->dst_dir, di->cmd_params->pid,
 		 dd->ident);
 	if (dd->type == MCD_BIN)
 		file = fopen(tmp_path, "wx");
@@ -2850,12 +2820,12 @@ static void copy_proc_files(struct dump_info *di, int tasks, const char *name,
 
 	snprintf(path, size, "%s/proc", di->dst_dir);
 	mkdir(path, 0700);
-	snprintf(path, size, "%s/proc/%d", di->dst_dir, di->pid);
+	snprintf(path, size, "%s/proc/%d", di->dst_dir, di->cmd_params->pid);
 	mkdir(path, 0700);
 
 	/* handle non-task file */
 	if (!tasks) {
-		snprintf(path, size, "%s/proc/%d/%s", di->dst_dir, di->pid,
+		snprintf(path, size, "%s/proc/%d/%s", di->dst_dir, di->cmd_params->pid,
 			 name);
 		if (link)
 			copy_link(path, path + base_len);
@@ -2865,18 +2835,18 @@ static void copy_proc_files(struct dump_info *di, int tasks, const char *name,
 		return;
 	}
 
-	snprintf(path, size, "%s/proc/%d/task", di->dst_dir, di->pid);
+	snprintf(path, size, "%s/proc/%d/task", di->dst_dir, di->cmd_params->pid);
 	mkdir(path, 0700);
 
 	for (i = 0 ; i < di->ntsks; i++) {
 		snprintf(path, size, "%s/proc/%d/task/%d", di->dst_dir,
-			 di->pid, di->tsks[i]);
+			 di->cmd_params->pid, di->tsks[i]);
 		mkdir(path, 0700);
 
 		/* handle the normal task case */
 		if (!do_fds) {
 			snprintf(path, size, "%s/proc/%d/task/%d/%s",
-				 di->dst_dir, di->pid, di->tsks[i], name);
+				 di->dst_dir, di->cmd_params->pid, di->tsks[i], name);
 
 			if (link)
 				copy_link(path, path + base_len);
@@ -2887,7 +2857,7 @@ static void copy_proc_files(struct dump_info *di, int tasks, const char *name,
 
 		/* special case: copy the symlinks in the fd directory */
 		snprintf(path, size, "%s/proc/%d/task/%d/fd", di->dst_dir,
-			 di->pid, di->tsks[i]);
+			 di->cmd_params->pid, di->tsks[i]);
 		mkdir(path, 0700);
 
 		d = opendir(path + base_len);
@@ -2904,7 +2874,7 @@ static void copy_proc_files(struct dump_info *di, int tasks, const char *name,
 				continue;
 
 			snprintf(path, size, "%s/proc/%d/task/%d/fd/%s",
-				 di->dst_dir, di->pid, di->tsks[i],
+				 di->dst_dir, di->cmd_params->pid, di->tsks[i],
 				 de->d_name);
 
 			copy_link(path, path + base_len);
@@ -2933,7 +2903,7 @@ static int get_robust_mutex_list(struct dump_info *di)
 	size_t len;
 	long ret;
 
-	ret = __sys_get_robust_list(di->pid,
+	ret = __sys_get_robust_list(di->cmd_params->pid,
 				    (struct robust_list_head **)&l_head, &len);
 	if (ret != 0 || len != sizeof(struct robust_list_head))
 		return -1;
@@ -3081,7 +3051,7 @@ ps_err_e ps_lsetfpregs(struct ps_prochandle *ph, lwpid_t lwpid,
 
 pid_t ps_getpid(struct ps_prochandle *ph)
 {
-	return ph->di->pid;
+	return ph->di->cmd_params->pid;
 }
 
 ps_err_e ps_pglobal_lookup(struct ps_prochandle *ph, const char *object_name,
@@ -3247,7 +3217,7 @@ static int get_so_list(struct dump_info *di)
 	int ret;
 	int fd;
 
-	if (asprintf(&filename, "/proc/%d/auxv", di->pid) == -1)
+	if (asprintf(&filename, "/proc/%d/auxv", di->cmd_params->pid) == -1)
 		return -1;
 
 	fd = open(filename, O_RDONLY);
@@ -3409,11 +3379,12 @@ static int add_dumplist_section(struct dump_info *di)
 }
 #endif
 
-static void do_dump(struct dump_info *di, int argc, char *argv[])
+static void do_dump(struct dump_info *di)
 {
 	int ret;
 
-	ret = init_di(di, argc, argv);
+	ret = init_di(di);
+
 	if (ret == 1) {
 		info("unable to create new dump info instance");
 		goto out;
@@ -3594,60 +3565,59 @@ out:
 	munmap(sh, map_size);
 }
 
-static int do_all_dumps(struct dump_info *di, int argc, char *argv[])
+static struct cmd_parameters* copy_cmd_params(struct cmd_parameters* cmd_params)
+{
+	struct cmd_parameters *new_params = (struct cmd_parameters*)malloc(sizeof(struct cmd_parameters));
+	if (new_params == NULL)
+		return NULL;
+
+	new_params->pid = cmd_params->pid;
+	new_params->uid = cmd_params->uid;
+	new_params->gid = cmd_params->gid;
+	new_params->signum = cmd_params->signum;
+	new_params->timestamp = cmd_params->timestamp;
+	new_params->hostname = cmd_params->hostname;
+	new_params->cfg_path = cmd_params->cfg_path;
+	new_params->exe_name = cmd_params->exe_name;
+
+	return new_params;
+}
+
+static int do_all_dumps(struct dump_info *di)
 {
 	struct config *cfg = NULL;
 	const char *recept;
 	bool live_dumper;
 	char *comm_base;
-	pid_t core_pid;
-	long timestamp;
 	char *comm;
 	char *exe;
 	char *p;
-	char *ext_argv[10] = {
-		argv[0],
-		argv[1],
-		argv[2],
-		argv[3],
-		"0",
-		argv[5],
-		argv[6],
-		"",
-		argv[8],
-		NULL
-	};
-
-	if (argc == 8) {
-		cfg = init_config(MCD_CONF_PATH "/minicoredumper.cfg.json");
-	} else if (argc == 9) {
-		info("using custom minicoredumper cfg: %s", argv[8]);
-		cfg = init_config(argv[8]);
-	} else {
-		fatal("wrong arg count, check /proc/sys/kernel/core_pattern");
-	}
+
+	struct cmd_parameters *orig_params, *ext_params;
+
+	ext_params = copy_cmd_params(di->cmd_params);
+	if (ext_params == NULL)
+		fatal("malloc for ext_params error: %m");
+
+	cfg = init_config(di->cmd_params->cfg_path);
 
 	if (!cfg)
 		fatal("unable to init config");
 
 	check_config(cfg);
 
-	core_pid = strtol(argv[1], &p, 10);
-	if (*p != 0)
-		return 1;
-
-	timestamp = strtol(argv[5], &p, 10);
-	if (*p != 0)
-		return 1;
+	ext_params->signum = 0;
+	ext_params->exe_name = "";
 
-	comm = alloc_comm(argv[7], core_pid);
+	comm = alloc_comm(di->cmd_params->exe_name, di->cmd_params->pid);
 	if (!comm)
 		return 1;
 
-	if (core_pid == 0)
+	if (di->cmd_params->pid == 0)
 		exe = strdup("");
 	else
-		exe = alloc_exe(core_pid);
+		exe = alloc_exe(di->cmd_params->pid);
+
 	if (!exe)
 		return 1;
 
@@ -3659,8 +3629,8 @@ static int do_all_dumps(struct dump_info *di, int argc, char *argv[])
 		comm_base = p + 1;
 	}
 
-	di->dst_dir = alloc_dst_dir(timestamp, cfg->base_dir,
-				    comm_base, core_pid);
+	di->dst_dir = alloc_dst_dir(di->cmd_params->timestamp, cfg->base_dir,
+				    comm_base, di->cmd_params->pid);
 	if (!di->dst_dir)
 		return 1;
 
@@ -3683,13 +3653,13 @@ static int do_all_dumps(struct dump_info *di, int argc, char *argv[])
 		int n;
 		int i;
 
-		alloc_registered_pids(core_pid, &pids, &n);
+		alloc_registered_pids(di->cmd_params->pid, &pids, &n);
 
 		/* pause all registered tasks */
 		for (i = 0; i < n; i++) {
 			if (pids[i] == 0)
 				continue;
-			if (pids[i] == core_pid)
+			if (pids[i] == di->cmd_params->pid)
 				continue;
 			if (ptrace_tree(PTRACE_SEIZE, pids[i]) != 0)
 				pids[i] = 0;
@@ -3697,22 +3667,30 @@ static int do_all_dumps(struct dump_info *di, int argc, char *argv[])
 				ptrace_tree(PTRACE_INTERRUPT, pids[i]);
 		}
 
+		orig_params = di->cmd_params;
+		di->cmd_params = ext_params;
 		/* dump all registered tasks */
 		for (i = 0; i < n; i++) {
+			char *p;
 			if (pids[i] == 0)
 				continue;
-			if (pids[i] == core_pid)
+			if (pids[i] == di->cmd_params->pid)
 				continue;
 			snprintf(pidstr, sizeof(pidstr), "%d", pids[i]);
-			ext_argv[1] = &pidstr[0];
-			do_dump(di, argc, ext_argv);
+
+			ext_params->pid = strtol(pidstr, &p, 10);
+			if (*p != 0)
+				fatal("invalid pid");
+
+			do_dump(di);
 		}
+		di->cmd_params = orig_params;
 
 		/* resume all registered tasks */
 		for (i = 0; i < n; i++) {
 			if (pids[i] == 0)
 				continue;
-			if (pids[i] == core_pid)
+			if (pids[i] == di->cmd_params->pid)
 				continue;
 			ptrace_tree(PTRACE_DETACH, pids[i]);
 		}
@@ -3721,9 +3699,11 @@ static int do_all_dumps(struct dump_info *di, int argc, char *argv[])
 			free(pids);
 	}
 
-	if (core_pid != 0) {
+	free(ext_params);
+
+	if (di->cmd_params->pid != 0) {
 		/* dump crashed task */
-		do_dump(di, argc, argv);
+		do_dump(di);
 	}
 
 	free(di->dst_dir);
@@ -3731,6 +3711,80 @@ static int do_all_dumps(struct dump_info *di, int argc, char *argv[])
 	return 0;
 }
 
+typedef enum {
+	ARG_PID = 1,
+	ARG_UID,
+	ARG_GID,
+	ARG_SIGNUM,
+	ARG_TIMESTAMP,
+	ARG_HOSTNAME,
+	ARG_EXE_NAME,
+	ARG_CONF_PATH,
+} cmd_prms;
+
+struct cmd_parameters* parse_args(char *argv[], int argc)
+{
+	if (argc < (ARG_EXE_NAME + 1) || argc > (ARG_CONF_PATH + 1))
+		fatal("wrong amount of command line parameters");
+
+	struct cmd_parameters *cmd_params = (struct cmd_parameters*)malloc(sizeof(struct cmd_parameters));
+	if (cmd_params == NULL)
+		fatal("malloc for cmd_parameters error: %m");
+
+	char *p;
+
+	cmd_params->pid = strtol(argv[ARG_PID], &p, 10);
+	if (*p != 0)
+		fatal("invalid pid");
+
+	cmd_params->uid = strtol(argv[ARG_UID], &p, 10);
+	if (*p != 0)
+		fatal("invalid uid");
+
+	cmd_params->gid = strtol(argv[ARG_GID], &p, 10);
+	if (*p != 0)
+		fatal("invalid gid");
+
+	cmd_params->signum = strtol(argv[ARG_SIGNUM], &p, 10);
+	if (*p != 0)
+		fatal("invalid signum");
+
+	cmd_params->timestamp = strtol(argv[ARG_TIMESTAMP], &p, 10);
+	if (*p != 0)
+		fatal("invalid timestamp");
+
+	cmd_params->hostname = argv[ARG_HOSTNAME];
+	if (!cmd_params->hostname)
+		fatal("invalid hostname");
+
+	cmd_params->exe_name = argv[ARG_EXE_NAME];
+	if (!cmd_params->exe_name)
+		fatal("invalid exe filename");
+
+	if (argc == ARG_CONF_PATH) {
+		cmd_params->cfg_path = MCD_CONF_PATH "/minicoredumper.cfg.json";
+	} else if (argc == ARG_CONF_PATH + 1) {
+		info("using custom minicoredumper cfg: %s", argv[ARG_CONF_PATH]);
+		cmd_params->cfg_path = argv[ARG_CONF_PATH];
+	} else {
+		fatal("wrong arg count, check /proc/sys/kernel/core_pattern");
+	}
+	return cmd_params;
+}
+
+void print_argv(int argc, char *argv[])
+{
+	char buff[1024];
+	int offset = 0;
+	for (int i = 0; i < argc; i++) {
+		int ret = snprintf(&buff[offset], 1024-offset, " %s", argv[i]);
+		if (ret < 0)
+			fatal("print command line arguments error");
+		offset += ret;
+	}
+	info("argv:%s", buff);
+}
+
 int main(int argc, char *argv[])
 {
 	struct dump_info di;
@@ -3752,14 +3806,14 @@ int main(int argc, char *argv[])
 	/* prevent memory paging to swap */
 	mlockall(MCL_CURRENT | MCL_FUTURE);
 
-	if (argc == 8 || argc == 9) {
-		info("argv: %s %s %s %s %s %s %s %s", argv[0], argv[1],
-		     argv[2], argv[3], argv[4], argv[5], argv[6], argv[7]);
-	} else {
-		fatal("wrong amount of command line parameters");
-	}
+	print_argv(argc, argv);
+
+	di.cmd_params = parse_args(argv, argc);
+
+	if (di.cmd_params == NULL)
+		fatal("wrong parameters");
 
-	do_all_dumps(&di, argc, argv);
+	do_all_dumps(&di);
 
 	closelog();
 	munlockall();
diff --git a/src/minicoredumper/corestripper.h b/src/minicoredumper/corestripper.h
index d8683e4..e1511f8 100644
--- a/src/minicoredumper/corestripper.h
+++ b/src/minicoredumper/corestripper.h
@@ -42,6 +42,17 @@ struct sym_data {
 	struct sym_data *next;
 };
 
+struct cmd_parameters {
+	pid_t pid;
+	uid_t uid;
+	gid_t gid;
+	int signum;
+	time_t timestamp;
+	char *hostname;
+	char *cfg_path;
+	char *exe_name;
+};
+
 struct dump_info {
 	struct config *cfg;
 
@@ -59,18 +70,13 @@ struct dump_info {
 
 	struct sym_data *sym_data_list;
 
-	/* from core_pattern */
-	pid_t pid;
-	uid_t uid;
-	gid_t gid;
 	pid_t first_pid;
-	int signum;
-	time_t timestamp;
-	char *hostname;
 	char *comm;
 
 	/* /proc/$PID/exe */
 	char *exe;
+	/* from core_pattern */
+	struct cmd_parameters *cmd_params;
 
 	pid_t *tsks;
 	int ntsks;
-- 
2.7.4




More information about the minicoredumper mailing list