diff --git a/libunwind.orig/src/dwarf/Gfde.c b/libunwind/src/dwarf/Gfde.c
index 8659624..0d3ea40 100644
--- a/libunwind.orig/src/dwarf/Gfde.c
+++ b/libunwind/src/dwarf/Gfde.c
@@ -340,7 +340,12 @@ dwarf_extract_proc_info_from_fde (unw_addr_space_t as, unw_accessors_t *a,
 	{
 	  if ((ret = dwarf_readu16 (as, a, &addr, &dci.abi, arg)) < 0
 	      || (ret = dwarf_readu16 (as, a, &addr, &dci.tag, arg)) < 0)
-	    return ret;
+	    {
+	      /* free unwind_info, it contains no info */
+	      mempool_free (&dwarf_cie_info_pool, pi->unwind_info);
+	      pi->unwind_info = NULL;
+	      return ret;
+	    }
 	  Debug (13, "Found ABI marker = (abi=%u, tag=%u)\n",
 		 dci.abi, dci.tag);
 	}
diff --git a/libunwind.orig/src/dwarf/Gfind_proc_info-lsb.c b/libunwind/src/dwarf/Gfind_proc_info-lsb.c
index d65342c..a2f27f8 100644
--- a/libunwind.orig/src/dwarf/Gfind_proc_info-lsb.c
+++ b/libunwind/src/dwarf/Gfind_proc_info-lsb.c
@@ -783,14 +783,31 @@ dwarf_find_proc_info (unw_addr_space_t as, unw_word_t ip,
 
   /* search the table: */
   if (cb_data.di.format != -1)
-    ret = dwarf_search_unwind_table (as, ip, &cb_data.di,
-				      pi, need_unwind_info, arg);
+    {
+      if (pi->unwind_info)
+	{
+	  /* free unwind_info allocated by callback above before allocating a new one */
+	  mempool_free (&dwarf_cie_info_pool, pi->unwind_info);
+	  pi->unwind_info = NULL;
+	}
+      ret = dwarf_search_unwind_table (as, ip, &cb_data.di,
+				       pi, need_unwind_info, arg);
+    }
   else
     ret = -UNW_ENOINFO;
 
   if (ret == -UNW_ENOINFO && cb_data.di_debug.format != -1)
-    ret = dwarf_search_unwind_table (as, ip, &cb_data.di_debug, pi,
-				     need_unwind_info, arg);
+    {
+      if (pi->unwind_info)
+	{
+	  /* free unwind_info allocated by callback above before allocating a new one */
+	  mempool_free (&dwarf_cie_info_pool, pi->unwind_info);
+	  pi->unwind_info = NULL;
+	}
+      ret = dwarf_search_unwind_table (as, ip, &cb_data.di_debug, pi,
+				       need_unwind_info, arg);
+    }
+
   return ret;
 }
 
@@ -960,7 +977,15 @@ dwarf_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
     }
 
   if (ip < pi->start_ip || ip >= pi->end_ip)
-    return -UNW_ENOINFO;
+    {
+      if (pi->unwind_info)
+	{
+	  /* free unwind_info, it contains bad info */
+	  mempool_free (&dwarf_cie_info_pool, pi->unwind_info);
+	  pi->unwind_info = NULL;
+	}
+      return -UNW_ENOINFO;
+    }
 
   return 0;
 }
diff --git a/libunwind.orig/src/dwarf/Gparser.c b/libunwind/src/dwarf/Gparser.c
index 13bd9a2..f70c7c2 100644
--- a/libunwind.orig/src/dwarf/Gparser.c
+++ b/libunwind/src/dwarf/Gparser.c
@@ -816,10 +816,18 @@ uncached_dwarf_find_save_locs (struct dwarf_cursor *c)
     return ret;
 
   if ((ret = create_state_record_for (c, &sr, c->ip)) < 0)
-    return ret;
+    {
+      /* free unwind_info alloc'd by fetch_proc_info above */
+      put_unwind_info (c, &c->pi);
+      return ret;
+    }
 
   if ((ret = apply_reg_state (c, &sr.rs_current)) < 0)
-    return ret;
+    {
+      /* free unwind_info alloc'd by fetch_proc_info above */
+      put_unwind_info (c, &c->pi);
+      return ret;
+    }
 
   put_unwind_info (c, &c->pi);
   return 0;
@@ -852,6 +860,8 @@ dwarf_find_save_locs (struct dwarf_cursor *c)
       if ((ret = fetch_proc_info (c, c->ip, 1)) < 0 ||
 	  (ret = create_state_record_for (c, &sr, c->ip)) < 0)
 	{
+	  /* free unwind_info alloc'd by fetch_proc_info above */
+	  put_unwind_info (c, &c->pi); 
 	  put_rs_cache (c->as, cache, &saved_mask);
 	  return ret;
 	}
