📄 740-debian_make-cv-type-crash.patch
字号:
2004-11-04 Jim Blandy <jimb@redhat.com> * gdbtypes.c (make_qualified_type): Doc fix. Add assertion to prevent cross-objfile references. (make_cv_type): Doc fix. Don't create cross-objfile references, even for stub types. (replace_type): Add assertion to prevent cross-objfile references. (check_typedef): Never resolve a stub type by copying over a type from another file.Index: src/gdb/gdbtypes.c===================================================================RCS file: /big/fsf/rsync/src-cvs/src/gdb/gdbtypes.c,vretrieving revision 1.92retrieving revision 1.93diff -u -p -r1.92 -r1.93--- src/gdb/gdbtypes.c 8 Aug 2004 17:18:16 -0000 1.92+++ src/gdb/gdbtypes.c 4 Nov 2004 17:50:16 -0000 1.93@@ -433,7 +433,9 @@ address_space_int_to_name (int space_fla } /* Create a new type with instance flags NEW_FLAGS, based on TYPE.- If STORAGE is non-NULL, create the new type instance there. */++ If STORAGE is non-NULL, create the new type instance there.+ STORAGE must be in the same obstack as TYPE. */ static struct type * make_qualified_type (struct type *type, int new_flags,@@ -453,6 +455,12 @@ make_qualified_type (struct type *type, ntype = alloc_type_instance (type); else {+ /* If STORAGE was provided, it had better be in the same objfile as+ TYPE. Otherwise, we can't link it into TYPE's cv chain: if one+ objfile is freed and the other kept, we'd have dangling+ pointers. */+ gdb_assert (TYPE_OBJFILE (type) == TYPE_OBJFILE (storage));+ ntype = storage; TYPE_MAIN_TYPE (ntype) = TYPE_MAIN_TYPE (type); TYPE_CHAIN (ntype) = ntype;@@ -501,11 +509,12 @@ make_type_with_address_space (struct typ CNST is a flag for setting the const attribute VOLTL is a flag for setting the volatile attribute TYPE is the base type whose variant we are creating.- TYPEPTR, if nonzero, points- to a pointer to memory where the reference type should be stored.- If *TYPEPTR is zero, update it to point to the reference type we return.- We allocate new memory if needed. */ + If TYPEPTR and *TYPEPTR are non-zero, then *TYPEPTR points to+ storage to hold the new qualified type; *TYPEPTR and TYPE must be+ in the same objfile. Otherwise, allocate fresh memory for the new+ type whereever TYPE lives. If TYPEPTR is non-zero, set it to the+ new type we construct. */ struct type * make_cv_type (int cnst, int voltl, struct type *type, struct type **typeptr) {@@ -524,20 +533,19 @@ make_cv_type (int cnst, int voltl, struc if (typeptr && *typeptr != NULL) {- /* Objfile is per-core-type. This const-qualified type had best- belong to the same objfile as the type it is qualifying, unless- we are overwriting a stub type, in which case the safest thing- to do is to copy the core type into the new objfile. */-- gdb_assert (TYPE_OBJFILE (*typeptr) == TYPE_OBJFILE (type)- || TYPE_STUB (*typeptr));- if (TYPE_OBJFILE (*typeptr) != TYPE_OBJFILE (type))- {- TYPE_MAIN_TYPE (*typeptr)- = TYPE_ALLOC (*typeptr, sizeof (struct main_type));- *TYPE_MAIN_TYPE (*typeptr)- = *TYPE_MAIN_TYPE (type);- }+ /* TYPE and *TYPEPTR must be in the same objfile. We can't have+ a C-V variant chain that threads across objfiles: if one+ objfile gets freed, then the other has a broken C-V chain.++ This code used to try to copy over the main type from TYPE to+ *TYPEPTR if they were in different objfiles, but that's+ wrong, too: TYPE may have a field list or member function+ lists, which refer to types of their own, etc. etc. The+ whole shebang would need to be copied over recursively; you+ can't have inter-objfile pointers. The only thing to do is+ to leave stub types as stub types, and look them up afresh by+ name each time you encounter them. */+ gdb_assert (TYPE_OBJFILE (*typeptr) == TYPE_OBJFILE (type)); } ntype = make_qualified_type (type, new_flags, typeptr ? *typeptr : NULL);@@ -562,6 +570,12 @@ replace_type (struct type *ntype, struct { struct type *chain; + /* These two types had better be in the same objfile. Otherwise,+ the assignment of one type's main type structure to the other+ will produce a type with references to objects (names; field+ lists; etc.) allocated on an objfile other than its own. */+ gdb_assert (TYPE_OBJFILE (ntype) == TYPE_OBJFILE (ntype));+ *TYPE_MAIN_TYPE (ntype) = *TYPE_MAIN_TYPE (type); /* The type length is not a part of the main type. Update it for each@@ -1416,8 +1430,24 @@ check_typedef (struct type *type) return type; } newtype = lookup_transparent_type (name);+ if (newtype)- make_cv_type (is_const, is_volatile, newtype, &type);+ {+ /* If the resolved type and the stub are in the same objfile,+ then replace the stub type with the real deal. But if+ they're in separate objfiles, leave the stub alone; we'll+ just look up the transparent type every time we call+ check_typedef. We can't create pointers between types+ allocated to different objfiles, since they may have+ different lifetimes. Trying to copy NEWTYPE over to TYPE's+ objfile is pointless, too, since you'll have to move over any+ other types NEWTYPE refers to, which could be an unbounded+ amount of stuff. */+ if (TYPE_OBJFILE (newtype) == TYPE_OBJFILE (type))+ make_cv_type (is_const, is_volatile, newtype, &type);+ else+ type = newtype;+ } } /* Otherwise, rely on the stub flag being set for opaque/stubbed types */ else if (TYPE_STUB (type) && !currently_reading_symtab)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -