Version 0.2.9
* Bug#20616 wasn't completely fixed; it didn't work with some programs (Fixed)
* Stopping ltrace with ^C DIDN'T WORK if -p option is not used!! (Fixed)
* Option -f caused program to segfault; fixed
* Fixed nasty bug about executing set[ug]id binaries:
When executing a program fails, don't left the program STOPPED.
* Make ltrace work with all setuid and setgid binaries when invoked as root
diff --git a/ltrace.c b/ltrace.c
index 1ce1108..bb7eef8 100644
--- a/ltrace.c
+++ b/ltrace.c
@@ -5,21 +5,27 @@
#include <errno.h>
#include <sys/param.h>
#include <signal.h>
+#include <sys/wait.h>
#include "ltrace.h"
-#include "elf.h"
#include "output.h"
-#include "config_file.h"
+#include "read_config_file.h"
#include "options.h"
char * command = NULL;
struct process * list_of_processes = NULL;
+int exiting=0; /* =1 if a SIGINT or SIGTERM has been received */
+
static void normal_exit(void);
static void signal_exit(int);
+static pid_t my_pid;
int main(int argc, char **argv)
{
+ struct opt_p_t * opt_p_tmp;
+
+ my_pid = getpid();
atexit(normal_exit);
signal(SIGINT,signal_exit); /* Detach processes when interrupted */
signal(SIGTERM,signal_exit); /* ... or killed */
@@ -32,32 +38,67 @@
strcat(path, "/.ltrace.conf");
read_config_file(path);
}
- while (opt_p) {
- open_pid(opt_p->pid, 1);
- opt_p = opt_p->next;
- }
if (command) {
execute_program(open_program(command), argv);
}
+ opt_p_tmp = opt_p;
+ while (opt_p_tmp) {
+ open_pid(opt_p_tmp->pid, 1);
+ opt_p_tmp = opt_p_tmp->next;
+ }
while(1) {
process_event(wait_for_something());
}
}
+static void signal_alarm(int sig)
+{
+ struct process * tmp = list_of_processes;
+
+ 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;
+ }
+ break;
+ }
+ tmp2 = tmp2->next;
+ }
+ if (opt_d>1) {
+ output_line(0,"Sending SIGSTOP to process %u\n",tmp->pid);
+ }
+ kill(tmp->pid, SIGSTOP);
+ tmp = tmp->next;
+ }
+}
+
static void signal_exit(int sig)
{
- exit(2);
+ exiting=1;
+ if (opt_d) {
+ output_line(0,"Received interrupt signal; exiting...");
+ }
+ signal(SIGINT,SIG_IGN);
+ signal(SIGTERM,SIG_IGN);
+ signal(SIGALRM,signal_alarm);
+ if (opt_p) {
+ struct opt_p_t * tmp = opt_p;
+ while(tmp) {
+ if (opt_d>1) {
+ output_line(0,"Sending SIGSTOP to process %u\n",tmp->pid);
+ }
+ kill(tmp->pid, SIGSTOP);
+ tmp = tmp->next;
+ }
+ }
+ alarm(1);
}
static void normal_exit(void)
{
- struct process * tmp = list_of_processes;
-
- while(tmp) {
- kill(tmp->pid, SIGSTOP);
- disable_all_breakpoints(tmp);
- continue_process(tmp->pid);
- untrace_pid(tmp->pid);
- tmp = tmp->next;
- }
+ output_line(0,0);
}