Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > media > main-src > by-pkgid > b3bd92884018251b87f9099340c300c3 > files > 46

ltrace-0.5-13.45svn.el5_7.12.src.rpm

diff -urp /usr/src/redhat/BUILD/ltrace-0.5/wait_for_something.c ltrace-0.5-64/wait_for_something.c
--- /usr/src/redhat/BUILD/ltrace-0.5/wait_for_something.c	2011-10-25 17:35:00.000000000 -0400
+++ ltrace-0.5-64/wait_for_something.c	2011-10-25 16:17:31.000000000 -0400
@@ -165,6 +168,7 @@ struct event *wait_for_something(void)
 	pid_t pid, child_pid;
 	int status;
 	int tmp;
+	int stop_signal;
 
 	struct event * ev;
 	if ((ev = next_qd_event()) != NULL) {
@@ -292,16 +296,30 @@ struct event *wait_for_something(void)
 		event.thing = LT_EV_UNKNOWN;
 		return &event;
 	}
-	if ((WSTOPSIG(status) != (SIGTRAP | event.proc->tracesysgood)) &&
-	    (WSTOPSIG(status) != SIGTRAP)) {
+
+	stop_signal = WSTOPSIG(status);
+	event.thing = LT_EV_NONE;
+
+	void * addr = event.proc->instruction_pointer - DECR_PC_AFTER_BREAK;
+
+	/* On some targets (ia64, s390x), breakpoints are signalled
+	   not using SIGTRAP, but also with SIGILL, SIGSEGV or SIGEMT.
+	   Check for these. */
+	if (stop_signal == SIGSEGV || stop_signal == SIGILL) {
+		if (address2bpstruct(leader, addr))
+			stop_signal = SIGTRAP;
+	}
+
+	if (event.thing == LT_EV_NONE
+	    && (stop_signal != (SIGTRAP | event.proc->tracesysgood))
+	    && (stop_signal != SIGTRAP)) {
 		event.thing = LT_EV_SIGNAL;
-		event.e_un.signum = WSTOPSIG(status);
+		event.e_un.signum = stop_signal;
 		return &event;
 	}
 
 	event.thing = LT_EV_BREAKPOINT;
-	event.e_un.brk_addr =
-	    event.proc->instruction_pointer - DECR_PC_AFTER_BREAK;
+	event.e_un.brk_addr = addr;
 	return &event;
 }