Patch: Fix libunwind segfault when -p is passed before -k

Dmitry V. Levin ldv at altlinux.org
Wed Dec 14 00:06:52 UTC 2016


On Mon, Dec 12, 2016 at 01:53:29PM +0300, Dmitry V. Levin wrote:
> On Thu, Dec 08, 2016 at 10:00:59AM -1000, Sean Stangl wrote:
> > There is a segfault if strace is called as `strace -p 2260 -k`.
> > 
> > The -k flag sets a global bool stack_trace_enabled. But -p already consults
> > stack_trace_enabled during tcb initialization. So if -p is passed first,
> > the libunwind components of the tcb are uninitialized.
> 
> Good catch, thanks!
> 
> > The attached patch fixes this issue by having -k ensure that the libunwind
> > components are initialized.
> 
> I think the patch needs a guard against multiple -k options to avoid
> multiple late_unwind_tcb_init() invocations.

This is the patch I've applied:

diff --git a/strace.c b/strace.c
index 1b8b5cc..56fdfde 100644
--- a/strace.c
+++ b/strace.c
@@ -1769,8 +1769,14 @@ init(int argc, char *argv[])
 	}
 
 #ifdef USE_LIBUNWIND
-	if (stack_trace_enabled)
+	if (stack_trace_enabled) {
+		unsigned int tcbi;
+
 		unwind_init();
+		for (tcbi = 0; tcbi < tcbtabsize; ++tcbi) {
+			unwind_tcb_init(tcbtab[tcbi]);
+		}
+	}
 #endif
 
 	/* See if they want to run as another user. */
diff --git a/unwind.c b/unwind.c
index 238e215..326d184 100644
--- a/unwind.c
+++ b/unwind.c
@@ -103,6 +103,9 @@ unwind_init(void)
 void
 unwind_tcb_init(struct tcb *tcp)
 {
+	if (tcp->libunwind_ui)
+		return;
+
 	tcp->libunwind_ui = _UPT_create(tcp->pid);
 	if (!tcp->libunwind_ui)
 		die_out_of_memory();
-- 
ldv
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20161214/0c01710d/attachment.bin>


More information about the Strace-devel mailing list