X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=libltrace.c;h=a8dd61e74af6db2570f5438fa1135ae8e947211a;hb=e6c25f6799825812e2b87990333c649ba796f600;hp=0f48d1187396f966e805a08fbc23b237b5e6355f;hpb=59749d048d9e452f049f9151735b5256756919c3;p=platform%2Fupstream%2Fltrace.git diff --git a/libltrace.c b/libltrace.c index 0f48d11..a8dd61e 100644 --- a/libltrace.c +++ b/libltrace.c @@ -1,69 +1,98 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012,2013 Petr Machata, Red Hat Inc. + * Copyright (C) 2009 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include "config.h" +#include +#include +#include +#include +#include +#include #include #include -#include #include -#include -#include -#include -#include +#include #include "common.h" +#include "proc.h" +#include "read_config_file.h" +#include "backend.h" +#include "prototype.h" char *command = NULL; -Process *list_of_processes = NULL; int exiting = 0; /* =1 if a SIGINT or SIGTERM has been received */ -static void -signal_alarm(int sig) { - Process *tmp = list_of_processes; +static enum callback_status +stop_non_p_processes(struct process *proc, void *data) +{ + int stop = 1; - signal(SIGALRM, SIG_DFL); - while (tmp) { - struct opt_p_t *tmp2 = opt_p; - while (tmp2) { - if (tmp->pid == tmp2->pid) { - tmp = tmp->next; - if (!tmp) { - return; - } - tmp2 = opt_p; - continue; - } - tmp2 = tmp2->next; + struct opt_p_t *it; + for (it = opt_p; it != NULL; it = it->next) { + struct process *p_proc = pid2proc(it->pid); + if (p_proc == NULL) { + printf("stop_non_p_processes: %d terminated?\n", it->pid); + continue; + } + if (p_proc == proc || p_proc->leader == proc->leader) { + stop = 0; + break; } - debug(2, "Sending SIGSTOP to process %u\n", tmp->pid); - kill(tmp->pid, SIGSTOP); - tmp = tmp->next; } + + if (stop) { + debug(2, "Sending SIGSTOP to process %u", proc->pid); + kill(proc->pid, SIGSTOP); + } + + return CBS_CONT; +} + +static void +signal_alarm(int sig) { + signal(SIGALRM, SIG_DFL); + each_process(NULL, &stop_non_p_processes, NULL); } static void -signal_exit(int sig) { - exiting = 1; - debug(1, "Received interrupt signal; exiting..."); +signal_exit(int sig) +{ + if (exiting != 0) + return; + + exiting = 1 + !!os_ltrace_exiting_sighandler(); + signal(SIGINT, SIG_IGN); signal(SIGTERM, SIG_IGN); signal(SIGALRM, signal_alarm); - if (opt_p) { - struct opt_p_t *tmp = opt_p; - while (tmp) { - debug(2, "Sending SIGSTOP to process %u\n", tmp->pid); - kill(tmp->pid, SIGSTOP); - tmp = tmp->next; - } - } - alarm(1); + //alarm(1); } static void -normal_exit(void) { - output_line(0, 0); - if (options.summary) { +normal_exit(void) +{ + if (options.summary) show_summary(); - } if (options.output) { fclose(options.output); options.output = NULL; @@ -71,7 +100,10 @@ normal_exit(void) { } void -ltrace_init(int argc, char **argv) { +ltrace_init(int argc, char **argv) +{ + setlocale(LC_ALL, ""); + struct opt_p_t *opt_p_tmp; atexit(normal_exit); @@ -79,36 +111,25 @@ ltrace_init(int argc, char **argv) { signal(SIGTERM, signal_exit); /* ... or killed */ argv = process_options(argc, argv); - while (opt_F) { - /* If filename begins with ~, expand it to the user's home */ - /* directory. This does not correctly handle ~yoda, but that */ - /* isn't as bad as it seems because the shell will normally */ - /* be doing the expansion for us; only the hardcoded */ - /* ~/.ltrace.conf should ever use this code. */ - if (opt_F->filename[0] == '~') { - char path[PATH_MAX]; - char *home_dir = getenv("HOME"); - if (home_dir) { - strncpy(path, home_dir, PATH_MAX - 1); - path[PATH_MAX - 1] = '\0'; - strncat(path, opt_F->filename + 1, - PATH_MAX - strlen(path) - 1); - read_config_file(path); - } - } else { - read_config_file(opt_F->filename); - } - opt_F = opt_F->next; - } - if (opt_e) { - struct opt_e_t *tmp = opt_e; - while (tmp) { - debug(1, "Option -e: %s\n", tmp->name); - tmp = tmp->next; - } - } + init_global_config(); + if (command) { - execute_program(open_program(command, 0), argv); + /* Check that the binary ABI is supported before + * calling execute_program. */ + struct ltelf lte; + ltelf_init(<e, command); + ltelf_destroy(<e); + + pid_t pid = execute_program(command, argv); + struct process *proc = open_program(command, pid); + if (proc == NULL) { + fprintf(stderr, "couldn't open program '%s': %s\n", + command, strerror(errno)); + exit(EXIT_FAILURE); + } + + trace_set_options(proc); + continue_process(pid); } opt_p_tmp = opt_p; while (opt_p_tmp) {