libunwind-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Libunwind-devel] [PATCH] dangling pointer in ia64/Gtables.c:unw_search_


From: Joel Brobecker
Subject: [Libunwind-devel] [PATCH] dangling pointer in ia64/Gtables.c:unw_search_ia64_unwind_table
Date: Mon, 26 Mar 2012 16:36:05 -0700

Hello,

We noticed the following problem after we started building libunwind
(version 0.98.5) with GCC 4.7.

What happens is that unw_search_ia64_unwind_table uses remote_lookup
to search a libunwind entry, and stores the result into a variable
defined locally; When the lookup succeeds, it then saves a reference
to that local in a variable whose scope is more global, thus creating
a dangling reference as soon as we leave the local variable's scope:

  else
    {
      struct ia64_table_entry ent;

      segbase = di->u.rti.segbase;
      if ((ret = remote_lookup (as, di->u.rti.table_data,
                                di->u.rti.table_len * sizeof (unw_word_t),
                                ip - segbase, &ent, arg)) < 0)
        return ret;
      if (ret)
        e = &ent;
    }
  [...]
  pi->start_ip = e->start_offset + segbase;
  pi->end_ip = e->end_offset + segbase;

It's been working so far, but some changes in GCC's optimizer now
make it inline the call to remote_lookup and then optimize out
the tail end of that function where it was supposed to set the
"info_offset" field of our struct ia64_table_entry.

The following patch was only tested with libunwin 0.98.5, but applied
almost cleanly on the HEAD, and it seems pretty clear that HEAD also
suffers from the same problem.  I would test it further on the head,
but I haven't been able to fix the last build issue I had on ia64-hpux
(mentioned when I sent the my previous series of patches).

src/ia64:

        * Gtables.c (unw_search_ia64_unwind_table): Move declaration
        of variable "ent" outside of "else" block to avoid having
        a dangling reference to an out-of-scope local.

---
 src/ia64/Gtables.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/src/ia64/Gtables.c b/src/ia64/Gtables.c
index 1a16a2e..5ed72f0 100644
--- a/src/ia64/Gtables.c
+++ b/src/ia64/Gtables.c
@@ -255,6 +255,7 @@ unw_search_ia64_unwind_table (unw_addr_space_t as, 
unw_word_t ip,
   unw_word_t addr, hdr_addr, info_addr, info_end_addr, hdr, *wp;
   const struct ia64_table_entry *e = NULL;
   unw_word_t handler_offset, segbase = 0;
+  struct ia64_table_entry ent;
   int ret, is_local;
 
   assert ((di->format == UNW_INFO_FORMAT_TABLE
@@ -275,8 +276,6 @@ unw_search_ia64_unwind_table (unw_addr_space_t as, 
unw_word_t ip,
 #ifndef UNW_LOCAL_ONLY
   else
     {
-      struct ia64_table_entry ent;
-
       segbase = di->u.rti.segbase;
       if ((ret = remote_lookup (as, di->u.rti.table_data,
                                di->u.rti.table_len * sizeof (unw_word_t),
-- 
1.7.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]