gdb/
authorJan Kratochvil <jan.kratochvil@redhat.com>
Tue, 19 Jul 2011 20:28:52 +0000 (20:28 +0000)
committerJan Kratochvil <jan.kratochvil@redhat.com>
Tue, 19 Jul 2011 20:28:52 +0000 (20:28 +0000)
Fix crash if referenced CU is aged out.
* dwarf2loc.c (per_cu_dwarf_call): New variable back_to, use to for
xfree of block.data.
(indirect_pieced_value): New variable back_to, use to for xfree of
baton.data.
(dwarf2_compile_expr_to_ax): New variable back_to, use to for xfree of
block.data.
* dwarf2read.c (dwarf2_find_base_address): New prototype.
(load_cu): New function from ...
(dw2_do_instantiate_symtab): ... the code here ...
(process_full_comp_unit): ... and here.
(dwarf2_fetch_die_location_block): Call load_cu first.  Call xmemdup on
retval.data.

gdb/testsuite/
Fix crash if referenced CU is aged out.
* gdb.dwarf2/dw2-op-call.exp (maintenance set dwarf2 max-cache-age 0):
New.
* gdb.dwarf2/implptr.exp: Likewise.

gdb/ChangeLog
gdb/dwarf2loc.c
gdb/dwarf2read.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.dwarf2/dw2-op-call.exp
gdb/testsuite/gdb.dwarf2/implptr.exp

index debc803015e9abcffde7f9b835af4c2d65198bd9..4d9eb04c7a9e7ffad978b92bce017d57b1ed5d84 100644 (file)
@@ -1,3 +1,19 @@
+2011-07-19  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       Fix crash if referenced CU is aged out.
+       * dwarf2loc.c (per_cu_dwarf_call): New variable back_to, use to for
+       xfree of block.data.
+       (indirect_pieced_value): New variable back_to, use to for xfree of
+       baton.data.
+       (dwarf2_compile_expr_to_ax): New variable back_to, use to for xfree of
+       block.data.
+       * dwarf2read.c (dwarf2_find_base_address): New prototype.
+       (load_cu): New function from ...
+       (dw2_do_instantiate_symtab): ... the code here ...
+       (process_full_comp_unit): ... and here.
+       (dwarf2_fetch_die_location_block): Call load_cu first.  Call xmemdup on
+       retval.data.
+
 2011-07-19  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        * dwarf2loc.c (indirect_pieced_value): Use check_typedef for VALUE's
index 9d4aa8dc41de550e6c9eb88622bdbc2466236cde..c29a07cbce8bf31a81a781cda120c01e685e75c7 100644 (file)
@@ -265,14 +265,19 @@ per_cu_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset,
                   void *baton)
 {
   struct dwarf2_locexpr_baton block;
+  struct cleanup *back_to;
 
   block = dwarf2_fetch_die_location_block (die_offset, per_cu,
                                           get_frame_pc, baton);
 
+  back_to = make_cleanup (xfree, (void *) block.data);
+
   /* DW_OP_call_ref is currently not supported.  */
   gdb_assert (block.per_cu == per_cu);
 
   dwarf_expr_eval (ctx, block.data, block.size);
+
+  do_cleanups (back_to);
 }
 
 /* Helper interface of per_cu_dwarf_call for dwarf2_evaluate_loc_desc.  */
@@ -966,6 +971,7 @@ indirect_pieced_value (struct value *value)
   struct dwarf_expr_piece *piece = NULL;
   struct value *result;
   LONGEST byte_offset;
+  struct cleanup *back_to;
 
   type = check_typedef (value_type (value));
   if (TYPE_CODE (type) != TYPE_CODE_PTR)
@@ -1013,10 +1019,14 @@ indirect_pieced_value (struct value *value)
                                           get_frame_address_in_block_wrapper,
                                           frame);
 
+  back_to = make_cleanup (xfree, (void *) baton.data);
+
   result = dwarf2_evaluate_loc_desc_full (TYPE_TARGET_TYPE (type), frame,
                                          baton.data, baton.size, baton.per_cu,
                                          byte_offset);
 
+  do_cleanups (back_to);
+
   return result;
 }
 
@@ -2123,12 +2133,14 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
          {
            struct dwarf2_locexpr_baton block;
            int size = (op == DW_OP_call2 ? 2 : 4);
+           struct cleanup *back_to;
 
            uoffset = extract_unsigned_integer (op_ptr, size, byte_order);
            op_ptr += size;
 
            block = dwarf2_fetch_die_location_block (uoffset, per_cu,
                                                     get_ax_pc, expr);
+           back_to = make_cleanup (xfree, (void *) block.data);
 
            /* DW_OP_call_ref is currently not supported.  */
            gdb_assert (block.per_cu == per_cu);
@@ -2136,6 +2148,8 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
            dwarf2_compile_expr_to_ax (expr, loc, arch, addr_size,
                                       block.data, block.data + block.size,
                                       per_cu);
+
+           do_cleanups (back_to);
          }
          break;
 
index da82a2e831cc0383fb29777871ff69022754c392..a84d356e2b998f341add47cee4b624cedf34fc03 100644 (file)
@@ -884,6 +884,9 @@ static void dwarf2_locate_sections (bfd *, asection *, void *);
 static void dwarf2_create_include_psymtab (char *, struct partial_symtab *,
                                            struct objfile *);
 
+static void dwarf2_find_base_address (struct die_info *die,
+                                     struct dwarf2_cu *cu);
+
 static void dwarf2_build_psymtabs_hard (struct objfile *);
 
 static void scan_partial_symbols (struct partial_die_info *,
@@ -1788,6 +1791,23 @@ create_quick_file_names_table (unsigned int nr_initial_entries)
                            delete_file_name_entry, xcalloc, xfree);
 }
 
+/* Read in PER_CU->CU.  This function is unrelated to symtabs, symtab would
+   have to be created afterwards.  You should call age_cached_comp_units after
+   processing PER_CU->CU.  dw2_setup must have been already called.  */
+
+static void
+load_cu (struct dwarf2_per_cu_data *per_cu)
+{
+  if (per_cu->from_debug_types)
+    read_signatured_type_at_offset (per_cu->objfile, per_cu->offset);
+  else
+    load_full_comp_unit (per_cu, per_cu->objfile);
+
+  dwarf2_find_base_address (per_cu->cu->dies, per_cu->cu);
+
+  gdb_assert (per_cu->cu != NULL);
+}
+
 /* Read in the symbols for PER_CU.  OBJFILE is the objfile from which
    this CU came.  */
 
@@ -1801,10 +1821,7 @@ dw2_do_instantiate_symtab (struct objfile *objfile,
 
   queue_comp_unit (per_cu, objfile);
 
-  if (per_cu->from_debug_types)
-    read_signatured_type_at_offset (objfile, per_cu->offset);
-  else
-    load_full_comp_unit (per_cu, objfile);
+  load_cu (per_cu);
 
   process_queue (objfile);
 
@@ -4714,8 +4731,6 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
 
   cu->list_in_scope = &file_symbols;
 
-  dwarf2_find_base_address (cu->dies, cu);
-
   /* Do line number decoding in read_file_scope () */
   process_die (cu->dies, cu);
 
@@ -13813,7 +13828,8 @@ follow_die_ref (struct die_info *src_die, struct attribute *attr,
 }
 
 /* Return DWARF block and its CU referenced by OFFSET at PER_CU.  Returned
-   value is intended for DW_OP_call*.  */
+   value is intended for DW_OP_call*.  You must call xfree on returned
+   dwarf2_locexpr_baton->data.  */
 
 struct dwarf2_locexpr_baton
 dwarf2_fetch_die_location_block (unsigned int offset,
@@ -13821,13 +13837,17 @@ dwarf2_fetch_die_location_block (unsigned int offset,
                                 CORE_ADDR (*get_frame_pc) (void *baton),
                                 void *baton)
 {
-  struct dwarf2_cu *cu = per_cu->cu;
+  struct dwarf2_cu *cu;
   struct die_info *die;
   struct attribute *attr;
   struct dwarf2_locexpr_baton retval;
 
   dw2_setup (per_cu->objfile);
 
+  if (per_cu->cu == NULL)
+    load_cu (per_cu);
+  cu = per_cu->cu;
+
   die = follow_die_offset (offset, &cu);
   if (!die)
     error (_("Dwarf Error: Cannot find DIE at 0x%x referenced in module %s"),
@@ -13864,6 +13884,12 @@ dwarf2_fetch_die_location_block (unsigned int offset,
       retval.size = DW_BLOCK (attr)->size;
     }
   retval.per_cu = cu->per_cu;
+
+  if (retval.data)
+    retval.data = xmemdup (retval.data, retval.size, retval.size);
+
+  age_cached_comp_units ();
+
   return retval;
 }
 
index 2d60ff195f01687440d165a3665d3b232dabba5b..e3b3adb8ec987a51f94148f66ea79d023fb33895 100644 (file)
@@ -1,3 +1,10 @@
+2011-07-19  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       Fix crash if referenced CU is aged out.
+       * gdb.dwarf2/dw2-op-call.exp (maintenance set dwarf2 max-cache-age 0):
+       New.
+       * gdb.dwarf2/implptr.exp: Likewise.
+
 2011-07-19  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        * gdb.dwarf2/implptr.S: Rebuilt.
index 3fcef0975964cdca17187f90d5d763d50120ba1e..33191333783a0ac2f7376e0879f133058ca7d908 100644 (file)
@@ -31,6 +31,9 @@ if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objdir}/${subdir}/${execu
 
 clean_restart $executable
 
+# Additional test to verify the referenced CU is not aged out.
+gdb_test_no_output "maintenance set dwarf2 max-cache-age 0"
+
 gdb_test "p array1" " = 1"
 gdb_test "p array2" " = 2" "array2 using DW_OP_call2"
 gdb_test "p array3" " = 3" "array3 using DW_OP_call4"
index 8f9b5fb41b4df54c6bdf063025dbbee22b83609e..562e983b0ef90d20fa7f264d99f058d87a8f4c50 100644 (file)
@@ -40,6 +40,9 @@ if {[prepare_for_testing ${testfile}.exp ${testfile}.x $srcfile $opts]} {
     return -1
 }
 
+# Additional test to verify the referenced CU is not aged out.
+gdb_test_no_output "maintenance set dwarf2 max-cache-age 0"
+
 if ![runto_main] {
     return -1
 }