master
31197 Commits
Author | SHA1 | Message | Date | |
---|---|---|---|---|
|
83a559f7b9 |
Remove unused variable un darwin_nat_target::resume
gdb/ChangeLog: * darwin-nat.c (darwin_nat_target::resume): Remove status variable. Change-Id: Ibcbdd6641a12252840c7dea9f388f4f8ce265e3d |
||
|
16e311ab6d |
gdb: Allow prologue detection via symbols for Intel compilers.
The next-gen Intel Fortran compiler isn't flang-based, but emits prologue_end in the same manner. As do the newer Intel C/C++ compilers. This allows prologue detection based on dwarf for all newer Intel compilers. The cut-off version was not chosen for any specific reason other than the effort to test this. gdb/Changelog: 2021-04-08 Felix Willgerodt <felix.willgerodt@intel.com> * i386-tdep.c (i386_skip_prologue): Use symbol table to find the prologue end for Intel compilers. * amd64-tdep.c (amd64_skip_prologue): Likewise. * producer.c (producer_is_icc_ge_19): New function. * producer.h (producer_is_icc_ge_19): New declaration. |
||
|
fbb3bcfcd8 |
gdb: Update producer check for Intel compilers.
The main goal of this patch is to get rid of a warning for the new Fortran compiler: (gdb) b 9 warning: Could not recognize version of Intel Compiler in: "Intel(R) Fortran 21.0-2087b" Breakpoint 1 at 0x4048cf: file comp.f90, line 9. While trying to fix this I analyzed DW_AT_producer of all latest Intel compilers for C, C++ and Fortran. They do no longer necessarily start with "Intel (R)" nor do they follow the internal and external version number scheme that the original patch for this check assumed. Some newer compilers even contradict the "intermediate" digit in the old version scheme and have the MINOR number as the second digit, even when having 3 or 4 digits overall. Therefore I rewrote the check to consider the first MAJOR.MINOR string found as the version number. This might not be 100% correct for some older internal compilers, but the only current user of this function is only checking for the major version anyway. Hence this should be reliable enough and extendable enough going forward. gdb/ChangeLog: 2021-04-08 Felix Willgerodt <felix.willgerodt@intel.com> * producer.c: (producer_is_icc): Update for new version scheme. (producer_parsing_tests): Update names and expected results. * producer.h: (producer_is_icc): Update comment accordingly. |
||
|
e97007b64a |
gdb: make target_ops::follow_fork return void
I noticed that all implementations return false, so target_ops::follow_fork doesn't really need to return a value. Change it to return void. gdb/ChangeLog: * target.h (struct target_ops) <follow_fork>: Return void. (target_follow_fork): Likewise. * target.c (default_follow_fork): Likewise. (target_follow_fork): Likewise. * infrun.c (follow_fork_inferior): Adjust. * fbsd-nat.h (class fbsd_nat_target) <follow_fork>: Return void. * fbsd-nat.c (fbsd_nat_target:::follow_fork): Likewise. * linux-nat.h (class linux_nat_target) <follow_fork>: Likewise. * linux-nat.c (linux_nat_target::follow_fork): Return void. * obsd-nat.h (class obsd_nat_target) <follow_fork>: Return void. * obsd-nat.c (obsd_nat_target::follow_fork): Likewise. * remote.c (class remote_target) <follow_fork>: Likewise. (remote_target::follow_fork): Likewise. * target-delegates.c: Re-generate. Change-Id: If908c2f68b29fa275be2b0b9deb41e4c6a1b7879 |
||
|
dc2b480f3d |
CTF: handle forward reference type
Added function fetch_tid_type which calls get_tid_type and will set up the type, associated with a tid, if it is not read in yet. Also implement function read_forward_type which handles the CTF_K_FORWARD kind. Expanded gdb.base/ctf-ptype.exp to add cases with forward references. gdb/ChangeLog: * ctfread.c (fetch_tid_type): New function, use throughout file. (read_forward_type): New function. (read_type_record): Call read_forward_type. gdb/testsuite/ChangeLog: * gdb.base/ctf-ptype.c: Add struct link containing a forward reference type. * gdb.base/ctf-ptype.exp: Add "ptype struct link". |
||
|
0a703a4ced |
gdb/fortran: handle dynamic types within arrays and structures
This commit replaces this patch: https://sourceware.org/pipermail/gdb-patches/2021-January/174933.html which was itself a replacement for this patch: https://sourceware.org/pipermail/gdb-patches/2020-July/170335.html The motivation behind the original patch can be seen in the new test, which currently gives a GDB session like this: (gdb) ptype var8 type = Type type6 PTR TO -> ( Type type2 :: ptr_1 ) PTR TO -> ( Type type2 :: ptr_2 ) End Type type6 (gdb) ptype var8%ptr_2 type = PTR TO -> ( Type type2 integer(kind=4) :: spacer Type type1, allocatable :: t2_array(:) <------ Issue #1 End Type type2 ) (gdb) ptype var8%ptr_2%t2_array Cannot access memory at address 0x38 <------ Issue #2 (gdb) Issue #1: Here we see the abstract dynamic type, rather than the resolved concrete type. Though in some cases the user might be interested in the abstract dynamic type, I think that in most cases showing the resolved concrete type will be of more use. Plus, the user can always figure out the dynamic type (by source code inspection if nothing else) given the concrete type, but it is much harder to figure out the concrete type given only the dynamic type. Issue #2: In this example, GDB evaluates the expression in EVAL_AVOID_SIDE_EFFECTS mode (due to ptype). The value returned for var8%ptr_2 will be a non-lazy, zero value of the correct dynamic type. However, when GDB asks about the type of t2_array this requires GDB to access the value of var8%ptr_2 in order to read the dynamic properties. As this value was forced to zero (thanks to the use of EVAL_AVOID_SIDE_EFFECTS) then GDB ends up accessing memory at a base of zero plus some offset. Both this patch, and my previous two attempts, have all tried to resolve this problem by stopping EVAL_AVOID_SIDE_EFFECTS replacing the result value with a zero value in some cases. This new patch is influenced by how Ada handles its tagged typed. There are plenty of examples in ada-lang.c, but one specific case is ada_structop_operation::evaluate. When GDB spots that we are dealing with a tagged (dynamic) type, and we're in EVAL_AVOID_SIDE_EFFECTS mode, then GDB re-evaluates the child operation in EVAL_NORMAL mode. This commit handles two cases like this specifically for Fortran, a new fortran_structop_operation, and the already existing fortran_undetermined, which is where we handle array accesses. In these two locations we spot when we are dealing with a dynamic type and re-evaluate the child operation in EVAL_NORMAL mode so that we are able to access the dynamic properties of the type. The rest of this commit message is my attempt to record why my previous patches failed. To understand my second patch, and why it failed lets consider two expressions, this Fortran expression: (gdb) ptype var8%ptr_2%t2_array --<A> Operation: STRUCTOP_STRUCT --(1) Operation: STRUCTOP_STRUCT --(2) Operation: OP_VAR_VALUE --(3) Symbol: var8 Block: 0x3980ac0 String: ptr_2 String: t2_array And this C expression: (gdb) ptype ptr && ptr->a == 3 --<B> Operation: BINOP_LOGICAL_AND --(4) Operation: OP_VAR_VALUE --(5) Symbol: ptr Block: 0x45a2a00 Operation: BINOP_EQUAL --(6) Operation: STRUCTOP_PTR --(7) Operation: OP_VAR_VALUE --(8) Symbol: ptr Block: 0x45a2a00 String: a Operation: OP_LONG --(9) Type: int Constant: 0x0000000000000003 In expression <A> we should assume that t2_array is of dynamic type. Nothing has dynamic type in expression <B>. This is how GDB currently handles expression <A>, in all cases, EVAL_AVOID_SIDE_EFFECTS or EVAL_NORMAL, an OP_VAR_VALUE operation always returns the real value of the symbol, this is not forced to a zero value even in EVAL_AVOID_SIDE_EFFECTS mode. This means that (3), (5), and (8) will always return a real lazy value for the symbol. However a STRUCTOP_STRUCT will always replace its result with a non-lazy, zero value with the same type as its result. So (2) will lookup the field ptr_2 and create a zero value with that type. In this case the type is a pointer to a dynamic type. Then, when we evaluate (1) to figure out the resolved type of t2_array, we need to read the types dynamic properties. These properties are stored in memory relative to the objects base address, and the base address is in var8%ptr_2, which we already figured out has the value zero. GDB then evaluates the DWARF expressions that take the base address, add an offset and dereference. GDB then ends up trying to access addresses like 0x16, 0x8, etc. To fix this, I proposed changing STRUCTOP_STRUCT so that instead of returning a zero value we instead returned the actual value representing the structure's field in the target. My thinking was that GDB would not try to access the value's contents unless it needed it to resolve a dynamic type. This belief was incorrect. Consider expression <B>. We already know that (5) and (8) will return real values for the symbols being referenced. The BINOP_LOGICAL_AND, operation (4) will evaluate both of its children in EVAL_AVOID_SIDE_EFFECTS in order to get the types, this is required for C++ operator lookup. This means that even if the value of (5) would result in the BINOP_LOGICAL_AND returning false (say, ptr is NULL), we still evaluate (6) in EVAL_AVOID_SIDE_EFFECTS mode. Operation (6) will evaluate both children in EVAL_AVOID_SIDE_EFFECTS mode, operation (9) is easy, it just returns a value with the constant packed into it, but (7) is where the problem lies. Currently in GDB this STRUCTOP_STRUCT will always return a non-lazy zero value of the correct type. When the results of (7) and (9) are back in the BINOP_LOGICAL_AND operation (6), the two values are passed to value_equal which performs the comparison and returns a result. Note, the two things compared here are the immediate value (9), and a non-lazy zero value from (7). However, with my proposed patch operation (7) no longer returns a zero value, instead it returns a lazy value representing the actual value in target memory. When we call value_equal in (6) this code causes GDB to try and fetch the actual value from target memory. If `ptr` is NULL then this will cause GDB to access some invalid address at an offset from zero, this will most likely fail, and cause GDB to throw an error instead of returning the expected type. And so, we can now describe the problem that we're facing. The way GDB's expression evaluator is currently written we assume, when in EVAL_AVOID_SIDE_EFFECTS mode, that any value returned from a child operation can safely have its content read without throwing an error. If child operations start returning real values (instead of the fake zero values), then this is simply not true. If we wanted to work around this then we would need to rewrite almost all operations (I would guess) so that EVAL_AVOID_SIDE_EFFECTS mode does not cause evaluation of an operation to try and read the value of a child operation. As an example, consider this current GDB code from eval.c: struct value * eval_op_equal (struct type *expect_type, struct expression *exp, enum noside noside, enum exp_opcode op, struct value *arg1, struct value *arg2) { if (binop_user_defined_p (op, arg1, arg2)) { return value_x_binop (arg1, arg2, op, OP_NULL, noside); } else { binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2); int tem = value_equal (arg1, arg2); struct type *type = language_bool_type (exp->language_defn, exp->gdbarch); return value_from_longest (type, (LONGEST) tem); } } We could change this function to be this: struct value * eval_op_equal (struct type *expect_type, struct expression *exp, enum noside noside, enum exp_opcode op, struct value *arg1, struct value *arg2) { if (binop_user_defined_p (op, arg1, arg2)) { return value_x_binop (arg1, arg2, op, OP_NULL, noside); } else { struct type *type = language_bool_type (exp->language_defn, exp->gdbarch); if (noside == EVAL_AVOID_SIDE_EFFECTS) return value_zero (type, VALUE_LVAL (arg1)); else { binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2); int tem = value_equal (arg1, arg2); return value_from_longest (type, (LONGEST) tem); } } } Now we don't call value_equal unless we really need to. However, we would need to make the same, or similar change to almost all operations, which would be a big task, and might not be a direction we wanted to take GDB in. So, for now, I'm proposing we go with the more targeted, Fortran specific solution, that does the minimal required in order to correctly resolve the dynamic types. gdb/ChangeLog: * f-exp.h (class fortran_structop_operation): New class. * f-exp.y (exp): Create fortran_structop_operation instead of the generic structop_operation. * f-lang.c (fortran_undetermined::evaluate): Re-evaluate expression as EVAL_NORMAL if the result type was dynamic so we can extract the actual array bounds. (fortran_structop_operation::evaluate): New function. gdb/testsuite/ChangeLog: * gdb.fortran/dynamic-ptype-whatis.exp: New file. * gdb.fortran/dynamic-ptype-whatis.f90: New file. |
||
|
30ab358668 |
gdb: allow casting to rvalue reference in more cases
It is not currently possible to cast some values to an rvaule reference. This happens when simple scalar values are cast to an rvalue reference of the same type, e.g.: int global_var; Then in GDB: (gdb) p static_cast<int&&> (global_var) Attempt to take address of value not located in memory. Which is clearly silly. The problem is that as part of the cast an intermediate value is created within GDB that becomes an lval_none rather than the original lval_memory. The casting logic basically goes like this: The call tree that leads to the error looks like this: value_cast value_cast value_ref value_addr error The first value_cast call is casting the value for 'global_var' to type 'int&&'. GDB spots that the target type is a reference, and so calls value_cast again, this time casting 'global_var' to type 'int'. We then call value_ref to convert the result of the second value_cast into a reference. Unfortunately, the second cast results in the value (for global_var) changing from an lval_memory to an lval_none. This is because int to int casting calls extract_unsigned_integer and then value_from_longest. In theory value_cast has a check at its head that should help in this case, the code is: if (value_type (arg2) == type) return arg2; However, this only works in some cases. In our case 'value_type (arg2)' will be an objfile owned type, while the type from the expression parser 'int&&' will be gdbarch owned. The pointers will not be equal, but the meaning of the type will be equal. I did consider making the int to int casting case smarter, but this obviously is only one example. We must also consider things like float to float, or pointer to pointer.... So, I instead decided to try and make the initial check smarter. Instead of a straight pointer comparison, I now propose that we use types_deeply_equal. If this is true then we are casting something back to its current type, in which case we can preserve the lval setting by using value_copy. gdb/ChangeLog: * valops.c (value_cast): Call value_deeply_equal before performing any cast. gdb/testsuite/ChangeLog: * gdb.cp/rvalue-ref-params.cc (f3): New function. (f4): New function. (global_int): New global variable. (global_float): Likeiwse. (main): Call both new functions. * gdb.cp/rvalue-ref-params.exp: Add new tests. |
||
|
5e18990f1f |
gdb: move cheap pointer equality check earlier in types_equal
I noticed that in types equal we start with a cheap pointer equality check, then resolve typedefs, then do a series of (semi-)expensive checks, including checking type names, before, finally performing another pointer equality check. We should hoist the second pointer equality check to immediately after we have resolved typedefs. This would save performing the more expensive checks. This isn't going to give any noticable performance improvement, I just spotted this in passing and figured I might as well commit the fix. There should be no user visible changes after this commit. gdb/ChangeLog: * gdbtypes.c (types_equal): Move pointer equality check earlier in the function. |
||
|
56d467f4ee |
gdb: handle relative paths to DWO files
DWARF allows .dwo file paths to be relative rather than absolute. When they are relative, DWARF uses DW_AT_comp_dir to find the .dwo file. DW_AT_comp_dir can also be relative, making the entire search patch for the .dwo file relative. In this case, GDB currently searches relative to its current working directory, i.e. the directory from which the debugger was launched, but not relative to the directory containing the built binary. This cannot be right, as the compiler, when generating the relative paths, knows where it's building the binary but can have no idea where the debugger will be launched. The correct thing is to add the directory containing the binary to the search paths used for resolving relative locations of dwo files. That is what this patch does. gdb/ChangeLog: * dwarf2/read.c (try_open_dwop_file): Add path for the binary to the search paths used resolve relative location of .dwo file. gdb/testsuite/ChangeLog: * gdb.dwarf2/fission-relative-dwo.c: New file. * gdb.dwarf2/fission-relative-dwo.exp: New file. |
||
|
1fd999d909 |
gdb: Handle missing .debug_str section
While messing with the Dwarf assembler (gdb/testsuite/lib/dwarf.exp) I managed to create an ELF which made use of DW_FORM_strp, but didn't include a .debug_str section. When I started GDB on this ELF, GDB crashed. I would have expected to get an error instead. I tracked this down to an unfortunate design choice in dwarf2_section_info, a class which wraps around a bfd section, and is used for reading in debug information. GBB creates many dwarf2_section_info objects, one for each debug section that might need to be read, then as we find the input bfd sections we associate them with the corresponding dwarf2_section_info. If no matching input bfd section is found then the dwarf2_section_info is left in an unassociated state, its internal bfd section pointer is null. If later GDB tries to read content from the dwarf2_section_info, for example, which trying to read the string associated with DW_FORM_strp, we spot that there is no associated bfd section and issue an error message. To make the users life easier, the error message includes the section name being looked for, and the bfd from which the section was obtained. However, we get the section name by calling bfd_section_name on the associated section, and we get the bfd filename by calling bfd_get_filename on the owner of the associated section. Of course, if there is no associated section then both the calls bfd_section_name and dwarf2_section_info::get_bfd_owner will result in undefined behaviour (e.g. a crash). The solution I propose in this patch is, I know, not ideal. I simply spot the case where there is no associated section, and print a simpler error message, leaving out the section name and filename. A better solution would involve redesigning dwarf2_section_info, we could associate each dwarf2_section_info with the initial bfd being parsed. We would then display this filename if there's nothing better to display (e.g. if we find a section in a dwo/dwp split dwarf file then we would probably use that filename in preference). Each dwarf2_section_info could also have the concept of the default section name that would be read for that section, for example, string data might appear in ".debug_str" or ".zdebug_str", but if neither is found, then it would probably be OK to just say ".debug_str" is missing. Anyway, I didn't do any of that redesign, I just wanted to stop GDB crashing for now, so instead we get this: Dwarf Error: DW_FORM_strp used without required section Which isn't the best, but in context, isn't too bad: Reading symbols from /path/to/executable... Dwarf Error: DW_FORM_strp used without required section (No debugging symbols found in /path/to/executable) I also added some asserts into dwarf2_section_info which should trigger before GDB crashes in future, if we trigger any other bad paths through this code. And there's a test for the specific issue I hit. gdb/ChangeLog: * dwarf2/section.c (dwarf2_section_info::get_bfd_owner): Add an assert. (dwarf2_section_info::get_file_name): Add an assert. (dwarf2_section_info::read_string): Display a minimal, sane error when the dwarf2_section_info is not associated with a bfd section. gdb/testsuite/ChangeLog: * gdb.dwarf2/dw2-using-debug-str.exp: Add an additional test. |
||
|
79c024436b |
gdb/py: fix gdb.parameter('data-directory')
It was reported on IRC that using gdb.parameter('data-directory') doesn't work correctly. The problem is that the data directory is stored in 'gdb_datadir', however the set/show command is associated with a temporary 'staged_gdb_datadir'. When the user does 'set data-directory VALUE', the VALUE is stored in 'staged_gdb_datadir' by GDB, then set_gdb_datadir is called. This in turn calls set_gdb_data_directory to copy the value from staged_gdb_datadir into gdb_datadir. However, set_gdb_data_directory will resolve relative paths, so the value stored in gdb_datadir might not match the value in staged_gdb_datadir. The Python gdb.parameter API fetches the parameter values by accessing the variable associated with the show command, so in this case staged_gdb_datadir. This causes two problems: 1. Initially staged_gdb_datadir is NULL, and remains as such until the user does 'set data-directory VALUE' (which might never happen), but gdb_datadir starts with GDB's default data-directory value. So initially from Python gdb.parameter('data-directory') will return the empty string, even though at GDB's CLI 'show data-directory' prints a real path. 2. If the user does 'set data-directory ./some/relative/path', GDB will resolve the relative path, thus, 'show data-directory' at the CLI will print an absolute path. However, the value is staged_gdb_datadir will still be the relative path, and gdb.parameter('data-directory') from Python will return the relative path. In this commit I fix both of these issues by: 1. Initialising the value in staged_gdb_datadir based on the initial value in gdb_datadir, and 2. In set_gdb_datadir, after calling set_gdb_data_directory, I copy the value in gdb_datadir back into staged_gdb_datadir. With these two changes in place the value in staged_gdb_datadir should always match the value in gdb_datadir, and accessing data-directory from Python should now work correctly. gdb/ChangeLog: * top.c (staged_gdb_datadir): Update comment. (set_gdb_datadir): Copy the value of gdb_datadir back into staged_datadir. (init_main): Initialise staged_gdb_datadir. gdb/testsuite/ChangeLog: * gdb.python/py-parameter.exp: Add test for reading data-directory using gdb.parameter API. |
||
|
340d00fb78 |
[gdb/breakpoints] Workaround missing line-table entry
When running test-case gdb.opt/inline-cmds.exp, we run into this KFAIL with gcc: ... Breakpoint 7, main () at gdb.opt/inline-cmds.c:71^M 71 result = 0; /* set breakpoint 3 here */^M (gdb) PASS: gdb.opt/inline-cmds.exp: continue to breakpoint: consecutive func1 next^M 73 func1 (); /* first call */^M (gdb) PASS: gdb.opt/inline-cmds.exp: next to first func1 next^M 75 marker ();^M (gdb) KFAIL: gdb.opt/inline-cmds.exp: next to second func1 (PRMS: gdb/25884) ... while with clang we have instead: ... next^M 74 func1 (); /* second call */^M (gdb) PASS: gdb.opt/inline-cmds.exp: next to second func1 ... The relevant bit of the test source is here in inline-cmds.c: ... 71 result = 0; /* set breakpoint 3 here */ 72 73 func1 (); /* first call */ 74 func1 (); /* second call */ 75 marker (); ... with func1 defined as: ... 33 inline __attribute__((always_inline)) int func1(void) 34 { 35 bar (); 36 return x * y; 37 } ... The corresponding insns are: ... 40050b: movl $0x0,0x200b1f(%rip) # 601034 <result> 400515: callq 40057b <bar> 40051a: callq 40057b <bar> 40051f: callq 400596 <marker> ... and the line number info is: ... Line number Starting address View Stmt 71 0x40050b x 35 0x400515 x 75 0x40051f x ... The line number info is missing an entry for the insn at 40051a, and that is causing the FAIL. This is a gcc issue, filed as PR gcc/98780 -" Missing line table entry for inlined stmt at -g -O0". [ For contrast, with clang we have an extra entry: ... Line number Starting address View Stmt 71 0x40050b x 35 0x400515 x 35 0x40051a 75 0x40051f x ... though it appears to be missing the start-of-statement marker. ] However, there is debug info that indicates that the insn at 40051a is not part of the line table entry for the insn at 400515: ... <2><1c4>: Abbrev Number: 8 (DW_TAG_inlined_subroutine) <1c5> DW_AT_abstract_origin: <0x2a2> <1c9> DW_AT_low_pc : 0x400515 <1d1> DW_AT_high_pc : 0x5 <1d9> DW_AT_call_file : 1 <1da> DW_AT_call_line : 73 <2><1db>: Abbrev Number: 8 (DW_TAG_inlined_subroutine) <1dc> DW_AT_abstract_origin: <0x2a2> <1e0> DW_AT_low_pc : 0x40051a <1e8> DW_AT_high_pc : 0x5 <1f0> DW_AT_call_file : 1 <1f1> DW_AT_call_line : 74 ... and indeed lldb manages to "next" from line 73 to line 74. Work around the missing line table entry, by using the inline frame info to narrow the stepping range in prepare_one_step. Tested on x86_64-linux. gdb/ChangeLog: 2021-04-06 Tom de Vries <tdevries@suse.de> PR breakpoints/25884 * infcmd.c (prepare_one_step): Using inline frame info to narrow stepping range. gdb/testsuite/ChangeLog: 2021-04-06 Tom de Vries <tdevries@suse.de> PR breakpoints/25884 * gdb.opt/inline-cmds.exp: Remove kfail. |
||
|
d811a7cf74 |
[gdb/tui] Fix len_without_escapes in tui-disasm.c
On openSUSE Tumbleweed I run into: ... FAIL: gdb.tui/basic.exp: asm window shows main ERROR: invalid command name "_csi_L" ... Using a minimal example, we get: ... $ gdb -q outputs/gdb.tui/basic/basic -ex "tui enable" -ex "layout asm" <TUI output> src/gdb/ui-style.c:243: internal-error: bool \ ui_file_style::parse(const char*, size_t*): Assertion `match == 0' failed. ... The problem is in len_without_escapes, where we detect the start of an escape sequence, but then pass ptr to style.parse while ptr no longer points to the escape due to the ptr++ in the while condition: ... while ((c = *ptr++) != '\0') { if (c == '\033') { ui_file_style style; size_t n_read; if (style.parse (ptr, &n_read)) ... Fix this by removing the ++ in the while condition, and adding ptr++ in the loop body where appropriate. Tested on x86_64-linux. gdb/ChangeLog: 2021-04-06 Tom de Vries <tdevries@suse.de> PR tui/27680 * tui/tui-disasm.c (len_without_escapes): Pass ptr pointing at escape to style.parse. |
||
|
306b445a6d |
gdb: fix internal error in avr_frame_unwind_cache
When trying to do pretty much anything that requires unwinding a frame on AVR, we get /home/simark/src/wt/avr/gdb/trad-frame.h:143: internal-error: LONGEST trad_frame_saved_reg::addr() const: Assertion `m_kind == trad_frame_saved_reg_kind::ADDR' failed. This is likely coming from the trad-frame refactor in |
||
|
9161c89ad8 |
gdb: remove objfile parameter from get_objfile_bfd_data
I noticed it was unused. I think that makes sense, as it shows that objfile_per_bfd_storage is not specific to one objfile (it can be shared by multiple objfiles that have the same bfd). There is one thing I wonder though, maybe I'm missing something. If the BFD doesn't require relocation, get_objfile_bfd_data stores the newly allocated object in objfiles_bfd_data, so we can assume that objfiles_bfd_data is the owner of the object. When the bfd's refcount drops to 0, the corresponding objfile_per_bfd_storage object in objfiles_bfd_data is deleted. But if the BFD requires relocation, get_objfile_bfd_data returns a newly allocated object that isn't kept anywhere else (and isn't shared). So the objfile becomes the owner of the objfile_per_bfd_storage object. In objfile::~objfile, we have this: if (obfd) gdb_bfd_unref (obfd); else delete per_bfd; I'm thinking that obfd could be non-nullptr, and it could require relocation. In that case, it would never be freed. Anyway, that's not really connected to this patch. gdb/ChangeLog: * objfiles.c (get_objfile_bfd_data): Remove objfile parameter, adjust callers. Change-Id: Ifa3158074ea6b42686780ba09d0c964b0cf14cf1 |
||
|
0072c87379 |
gdb: pass objfile_per_bfd_storage instead of objfile to partial_symtab
Since partial_symtab is supposed to be objfile-independent (since series [1]), I think it would make sense for partial_symtab to not take an objfile as a parameter in its constructor. This patch replaces that parameter with an objfile_per_bfd_storage parameter. The objfile is used for two things: - to get the objfile_name, for debug messages. We can get that name from the bfd instead. - to intern the partial symtab filename. Even though it goes through an objfile method, the request is actually forwarded to the underlying objfile_per_bfd_storage. So we can ask the new objfile_per_bfd_storage instead. In order to get a reference to the BFD from the objfile_per_bfd_storage, the BFD is saved in the objfile_per_bfd_storage object. [1] https://sourceware.org/pipermail/gdb-patches/2021-February/176625.html gdb/ChangeLog: * psympriv.h (struct partial_symtab) <partial_symtab>: Change objfile parameter for objfile_per_bfd_storage, adjust callers. (struct standard_psymtab) <standard_psymtab>: Likewise. (struct legacy_psymtab) <legacy_psymtab>: Likewise. * psymtab.c (partial_symtab::partial_symtab): Likewise. * ctfread.c (struct ctf_psymtab): Likewise. * dwarf2/read.h (struct dwarf2_psymtab): Likewise. * dwarf2/read.c (struct dwarf2_include_psymtab): Likewise. (dwarf2_create_include_psymtab): Likewise. * objfiles.h (struct objfile_per_bfd_storage) <objfile_per_bfd_storage>: Add bfd parameter, adjust callers. <get_bfd>: New method. <m_bfd>: New field. * objfiles.c (get_objfile_bfd_data): Adjust. Change-Id: I2ed3ab5d2e6f27d034bd4dc26ae2fae7b0b8a2b9 |
||
|
9984dd9994 |
gdb: use std::string in partial_symtab::partial_symtab / allocate_symtab
This simplifies the code a bit. gdb/ChangeLog: * psymtab.c (partial_symtab::partial_symtab): Change last_objfile_name to be an std::string. * symfile.c (allocate_symtab): Likewise. Change-Id: I3dfe217233ed9346c2abc04a9b1be0df69a90af8 |
||
|
4a4f97c129 |
gdb: add intern methods to objfile_per_bfd_storage
This allows keeping the objfile_per_bfd_storage implementation details into objfile_per_bfd_storage, instead of into objfile. And this makes the intern methods usable for code that only has an objfile_per_bfd_storage to work with. gdb/ChangeLog: * objfiles.h (struct objfile_per_bfd_storage) <intern>: New methods. (struct objfile) <intern>: Use objfile::objfile_per_bfd_storage::intern. Change-Id: Ifd54026c5efaeffafac9b84ff84c199acc7ce78a |
||
|
0672875f3c |
gdb: remove TYPE_FLAG_ENUM
gdb/ChangeLog: * gdbtypes.h (TYPE_FLAG_ENUM): Remove, replace all uses with type::is_flag_enum. Change-Id: I74e23893066eecd6df641045b859a6d6ebb13dd0 |
||
|
9902b32793 |
gdb: add type::is_flag_enum / type::set_is_flag_enum
Add the `is_flag_enum` and `set_is_flag_enum` methods on `struct type`, in order to remove the `TYPE_FLAG_ENUM` macro. In this patch, the macro is changed to use the getter, so all the call sites of the macro that are used as a setter are changed to use the setter method directly. The next patch will remove the macro completely. gdb/ChangeLog: * gdbtypes.h (struct type) <is_flag_enum, set_is_flag_enum>: New methods. (TYPE_FLAG_ENUM): Use type::is_flag_enum, change all write call sites to use type::set_is_flag_enum. Change-Id: I9c56c91626c8d784947ba94fcb97818526b81d1c |
||
|
3bc440a2c4 |
gdb: remove TYPE_DECLARED_CLASS
gdb/ChangeLog: * gdbtypes.h (TYPE_DECLARED_CLASS): Remove, replace all uses with type::is_declared_class. Change-Id: Ifecb2342417ecd7bf570c3205344b09d706daab2 |
||
|
aa70e35c71 |
gdb: add type::is_declared_class / type::set_is_declared_class
Add the `is_declared_class` and `set_is_declared_class` methods on `struct type`, in order to remove the `TYPE_DECLARED_CLASS` macro. In this patch, the macro is changed to use the getter, so all the call sites of the macro that are used as a setter are changed to use the setter method directly. The next patch will remove the macro completely. gdb/ChangeLog: * gdbtypes.h (struct type) <is_declared_class, set_is_declared_class>: New methods. (TYPE_DECLARED_CLASS): Use type::is_declared_class, change all write call sites to use type::set_is_declared_class. Change-Id: Idf08d32e137c885a0aba0a18f556a899c1cbfd68 |
||
|
bfb9f5dcfe |
Use importlib instead of imp module on python 3.4+
Python 3.4 has deprecated the imp module in favour of importlib. This patch avoids the DeprecationWarning. This warning is visible to users whose libpython.so has been compiled with --with-pydebug. Considering that even python 3.5 has reached end of life, would it be better to just use importlib and drop support for python 3.0 to 3.3? 2021-02-28 Boris Staletic <boris.staletic@gmail.com> * gdb/python/lib/gdb/__init__.py: Use importlib on python 3.4+ to avoid deprecation warnings. |
||
|
733f5eea6b |
Use startswith in gdb subfolder.
gdb/ChangeLog: * cp-name-parser.y: Use startswith instead of strncmp. * m2-exp.y: Likewise. * macroexp.c (substitute_args): Likewise. * mi/mi-main.c (command_notifies_uscc_observer): Likewise. * rust-exp.y: Likewise. |
||
|
af82f89db0 |
Remove two trivial functions from dwarf2/read.c
This removes dw2_map_matching_symbols and dw2_expand_symtabs_matching, merging them with their sole trivial callers. gdb/ChangeLog 2021-03-31 Tom Tromey <tom@tromey.com> * dwarf2/read.c (dwarf2_gdb_index::map_matching_symbols): Merge with dw2_map_matching_symbols. (dwarf2_gdb_index::expand_symtabs_matching): Merge with dw2_expand_symtabs_matching. |
||
|
3570682a2c |
Fix typo in dwarf2/stringify.h
Pedro pointed out a typo in a comment in dwarf2/stringify.h. This fixes it. gdb/ChangeLog 2021-03-31 Tom Tromey <tromey@adacore.com> * dwarf2/stringify.h: Fix typo. |
||
|
8a91fbdf3b |
gdb/dwarf: disable per-BFD resource sharing for -readnow objfiles
New in v2:
- Disable sharing only for -readnow objfiles, not all objfiles.
As described in PR 27541, we hit an internal error when loading a binary
the standard way and then loading it with the -readnow option:
$ ./gdb -nx -q --data-directory=data-directory ~/a.out -ex "set confirm off" -ex "file -readnow ~/a.out"
Reading symbols from /home/simark/a.out...
Reading symbols from ~/a.out...
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8098: internal-error: void create_all_comp_units(dwarf2_per_objfile*): Assertion `per_objfile->per_bfd->all_comp_units.empty ()' failed.
This is a recurring problem that exposes a design issue in the DWARF
per-BFD sharing feature. Things work well when loading a binary with
the same method (with/without index, with/without readnow) twice in a
row. But they don't work so well when loading a binary with different
methods. See this previous fix, for example:
|
||
|
9f67fc596b |
Remove parameter from language_info
I noticed that language_info is only ever called with a value of '1'. This patch removes the parameter. 2021-03-29 Tom Tromey <tromey@adacore.com> * top.c (check_frame_language_change): Update. * language.c (language_info): Remove parameter. * language.h (language_info): Remove parameter. |
||
|
9b8ffbf410 |
Don't pass empty options to GCC
On aarch64-linux, I noticed the compile command didn't work at all. It always gave the following error: aarch64-linux-gnu-g++: error: : No such file or directory Turns out we're passing an empty argv entry to GCC (because aarch64 doesn't have a -m64 option), and GCC's behavior is to think that is a file it needs to open. One can reproduce it like so: gcc "" "" "" "" gcc: error: : No such file or directory gcc: error: : No such file or directory gcc: error: : No such file or directory gcc: error: : No such file or directory gcc: fatal error: no input files compilation terminated. The solution is to check for an empty string and skip adding that to argv. Regression tested on aarch64-linux/Ubuntu 18.04/20.04. gdb/ChangeLog: 2021-03-29 Luis Machado <luis.machado@linaro.org> * compile/compile.c (get_args): Don't add empty argv entries. |
||
|
25b48839b3 |
Restore procfs.c compilation
Since
|
||
|
edc02ceb97 |
Simplify DWARF reader initialization
Now that the quick functions are separate from the object file format, there's no need to have elfread.c push a new entry on the objfile 'qf' list. Instead, this detail can be pushed into the DWARF reader. That is what this patch implements. I wasn't sure whether lazy reading still makes sense or not. It's still only used by ELF, and only in certain situations (like vfork, I think). It may not be carrying its weight, so we may want to consider removing this in the future. Also, I'm unclear on why the various indices are only used for ELF. This seems sub-optimal. However, I haven't tried to address that here. gdb/ChangeLog 2021-03-28 Tom Tromey <tom@tromey.com> * elfread.c (can_lazily_read_symbols): Move to dwarf2/read.c. (elf_symfile_read): Simplify. * dwarf2/read.c (struct lazy_dwarf_reader): Move from elfread.c. (make_lazy_dwarf_reader): New function. (make_dwarf_gdb_index, make_dwarf_debug_names): Now static. (dwarf2_initialize_objfile): Return void. Remove index_kind parameter. Push on 'qf' list. * dwarf2/public.h (dwarf2_initialize_objfile): Change return type. Remove 'index_kind' parameter. (make_dwarf_gdb_index, make_dwarf_debug_names): Don't declare. |
||
|
6e23d91aa7 |
Don't declare elf_sym_fns_lazy_psyms
An earlier patch neglected to delete a forward declaration of elf_sym_fns_lazy_psyms. This is no longer defined. This patch removes it. gdb/ChangeLog 2021-03-27 Tom Tromey <tom@tromey.com> * elfread.c (elf_sym_fns_lazy_psyms): Don't declare. |
||
|
594b8948eb |
Don't clear 'qf' in elf_symfile_read
I noticed that I forgot to make a change in my series to make it possible to attach multiple debug readers to an objfile. In one spot, elf_symfile_read still clears the 'qf' list. However, this should have been removed toward the end of that series. This patch fixes the offending spot. Tested on x86-64 Fedora 32. gdb/ChangeLog 2021-03-27 Tom Tromey <tom@tromey.com> * elfread.c (elf_symfile_read): Don't clear 'qf'. |
||
|
efe1ecd834 |
gdb-add-index.sh: Remove use of non posix 'local'
While working on gdb-add-index.sh, it appeared that it uses the non POSIX 'local' keyword. Instead of using local to allow variable shadowing, I rename the local one to avoid name conflicts altogether. This commit gets rid of the following shellcheck warning: In gdb-add-index.sh line 63: local file="$1" ^--------^ SC2039: In POSIX sh, 'local' is undefined. gdb/ChangeLog: * contrib/gdb-add-index.sh: Avoid variable shadowing and get rid of 'local'. |
||
|
f4655dee77 |
Use function view in quick_symbol_functions::map_symbol_filenames
This changes quick_symbol_functions::map_symbol_filenames to use a function_view, and updates all the uses. It also changes the final parameter to 'bool'. A couple of spots are further updated to use operator() rather than a lambda. gdb/ChangeLog 2021-03-26 Tom Tromey <tom@tromey.com> * symtab.c (struct output_source_filename_data): Add 'output' method and operator(). (output_source_filename_data::output): Rename from output_source_filename. (output_partial_symbol_filename): Remove. (info_sources_command): Update. (struct add_partial_filename_data): Add operator(). (add_partial_filename_data::operator()): Rename from maybe_add_partial_symtab_filename. (make_source_files_completion_list): Update. * symfile.c (quick_symbol_functions): Update. * symfile-debug.c (objfile::map_symbol_filenames): Update. * quick-symbol.h (symbol_filename_ftype): Change type of 'fun' and 'need_fullname'. Remove 'data' parameter. (struct quick_symbol_functions) <map_symbol_filenames>: Likewise. * psymtab.c (psymbol_functions::map_symbol_filenames): Update. * psympriv.h (struct psymbol_functions) <map_symbol_filenames>: Change type of 'fun' and 'need_fullname'. Remove 'data' parameter. * objfiles.h (struct objfile) <map_symbol_filenames>: Change type of 'fun' and 'need_fullname'. Remove 'data' parameter. * mi/mi-cmd-file.c (print_partial_file_name): Remove 'ignore' parameter. (mi_cmd_file_list_exec_source_files): Update. * dwarf2/read.c (dwarf2_base_index_functions::map_symbol_filenames): Update. |
||
|
2315bb2d57 |
Simplify use of map_matching_symbols in ada-lang.c
I noticed that ada-lang.c creates a lambda to call aux_add_nonlocal_symbols. However, this code can be simplified a bit by changing match_data to implement operator(), and then simply passing the object as the callback. That is what this patch implements. gdb/ChangeLog 2021-03-26 Tom Tromey <tom@tromey.com> * ada-lang.c (struct match_data): Add operator(). (match_data::operator()): Rename from aux_add_nonlocal_symbols. (callback): Remove 'callback'. |
||
|
e2cd5ca40c |
Simplify psymbol_functions::expand_symtabs_matching
I noticed that psymbol_functions::expand_symtabs_matching calls make_ignore_params once per psymtab that is matched. This seems possibly expensive, so this patch hoists the call out of the loop. gdb/ChangeLog 2021-03-26 Tom Tromey <tom@tromey.com> * psymtab.c (psymbol_functions::expand_symtabs_matching): Only call make_ignore_params once. |
||
|
cd43f63e00 |
Allow expand_symtabs_matching to examine imported psymtabs
Currently the psymtab variant of expand_symtabs_matching has this check: /* We skip shared psymtabs because file-matching doesn't apply to them; but we search them later in the loop. */ if (ps->user != NULL) continue; In a larger series I'm working on, it's convenient to remove this check. And, I noticed that a similar check is not done for expand_symtabs_with_fullname. So, it made sense to me to remove the check here as well. gdb/ChangeLog 2021-03-26 Tom Tromey <tom@tromey.com> * psymtab.c (psymbol_functions::expand_symtabs_matching): Remove "user" check. |
||
|
b4b1a226df |
gdb: defer commit resume until all available events are consumed
Rationale --------- Let's say you have multiple threads hitting a conditional breakpoint at the same time, and all of these are going to evaluate to false. All these threads will need to be resumed. Currently, GDB fetches one target event (one SIGTRAP representing the breakpoint hit) and decides that the thread should be resumed. It calls resume and commit_resume immediately. It then fetches the second target event, and does the same, until it went through all threads. The result is therefore something like: - consume event for thread A - resume thread A - commit resume (affects thread A) - consume event for thread B - resume thread B - commit resume (affects thread B) - consume event for thread C - resume thread C - commit resume (affects thread C) For targets where it's beneficial to group resumptions requests (most likely those that implement target_ops::commit_resume), it would be much better to have: - consume event for thread A - resume thread A - consume event for thread B - resume thread B - consume event for thread C - resume thread C - commit resume (affects threads A, B and C) Implementation details ---------------------- To achieve this, this patch adds another check in maybe_set_commit_resumed_all_targets to avoid setting the commit-resumed flag of targets that readily have events to provide to infrun. To determine if a target has events readily available to report, this patch adds an `has_pending_events` target_ops method. The method returns a simple bool to say whether or not it has pending events to report. Testing ======= To test this, I start GDBserver with a program that spawns multiple threads: $ ../gdbserver/gdbserver --once :1234 ~/src/many-threads-stepping-over-breakpoints/many-threads-stepping-over-breakpoints I then connect with GDB and install a conditional breakpoint that always evaluates to false (and force the evaluation to be done by GDB): $ ./gdb -nx --data-directory=data-directory \ /home/simark/src/many-threads-stepping-over-breakpoints/many-threads-stepping-over-breakpoints \ -ex "set breakpoint condition-evaluation host" \ -ex "set pag off" \ -ex "set confirm off" \ -ex "maint set target-non-stop on" \ -ex "tar rem :1234" \ -ex "tb main" \ -ex "b 13 if 0" \ -ex c \ -ex "set debug infrun" \ -ex "set debug remote 1" \ -ex "set debug displaced" I then do "continue" and look at the log. The remote target receives a bunch of stop notifications for all threads that have hit the breakpoint. infrun consumes and processes one event, decides it should not cause a stop, prepares a displaced step, after which we should see: [infrun] maybe_set_commit_resumed_all_process_targets: not requesting commit-resumed for target remote, target has pending events Same for a second thread (since we have 2 displaced step buffers). For the following threads, their displaced step is deferred since there are no more buffers available. After consuming the last event the remote target has to offer, we get: [infrun] maybe_set_commit_resumed_all_process_targets: enabling commit-resumed for target remote [infrun] maybe_call_commit_resumed_all_process_targets: calling commit_resumed for target remote [remote] Sending packet: $vCont;s:p14d16b.14d1b1;s:p14d16b.14d1b2#55 [remote] Packet received: OK Without the patch, there would have been one vCont;s just after each prepared displaced step. gdb/ChangeLog: yyyy-mm-dd Simon Marchi <simon.marchi@efficios.com> Pedro Alves <pedro@palves.net> * async-event.c (async_event_handler_marked): New. * async-event.h (async_event_handler_marked): Declare. * infrun.c (maybe_set_commit_resumed_all_targets): Switch to inferior before calling target method. Don't commit-resumed if target_has_pending_events is true. * remote.c (remote_target::has_pending_events): New. * target-delegates.c: Regenerate. * target.c (target_has_pending_events): New. * target.h (target_ops::has_pending_events): New target method. (target_has_pending_events): New. Change-Id: I18112ba19a1ff4986530c660f530d847bb4a1f1d |
||
|
1192f124a3 |
gdb: generalize commit_resume, avoid commit-resuming when threads have pending statuses
The rationale for this patch comes from the ROCm port [1], the goal being to reduce the number of back and forths between GDB and the target when doing successive operations. I'll start with explaining the rationale and then go over the implementation. In the ROCm / GPU world, the term "wave" is somewhat equivalent to a "thread" in GDB. So if you read if from a GPU stand point, just s/thread/wave/. ROCdbgapi, the library used by GDB [2] to communicate with the GPU target, gives the illusion that it's possible for the debugger to control (start and stop) individual threads. But in reality, this is not how it works. Under the hood, all threads of a queue are controlled as a group. To stop one thread in a group of running ones, the state of all threads is retrieved from the GPU, all threads are destroyed, and all threads but the one we want to stop are re-created from the saved state. The net result, from the point of view of GDB, is that the library stopped one thread. The same thing goes if we want to resume one thread while others are running: the state of all running threads is retrieved from the GPU, they are all destroyed, and they are all re-created, including the thread we want to resume. This leads to some inefficiencies when combined with how GDB works, here are two examples: - Stopping all threads: because the target operates in non-stop mode, when the user interface mode is all-stop, GDB must stop all threads individually when presenting a stop. Let's suppose we have 1000 threads and the user does ^C. GDB asks the target to stop one thread. Behind the scenes, the library retrieves 1000 thread states and restores the 999 others still running ones. GDB asks the target to stop another one. The target retrieves 999 thread states and restores the 998 remaining ones. That means that to stop 1000 threads, we did 1000 back and forths with the GPU. It would have been much better to just retrieve the states once and stop there. - Resuming with pending events: suppose the 1000 threads hit a breakpoint at the same time. The breakpoint is conditional and evaluates to true for the first thread, to false for all others. GDB pulls one event (for the first thread) from the target, decides that it should present a stop, so stops all threads using stop_all_threads. All these other threads have a breakpoint event to report, which is saved in `thread_info::suspend::waitstatus` for later. When the user does "continue", GDB resumes that one thread that did hit the breakpoint. It then processes the pending events one by one as if they just arrived. It picks one, evaluates the condition to false, and resumes the thread. It picks another one, evaluates the condition to false, and resumes the thread. And so on. In between each resumption, there is a full state retrieval and re-creation. It would be much nicer if we could wait a little bit before sending those threads on the GPU, until it processed all those pending events. To address this kind of performance issue, ROCdbgapi has a concept called "forward progress required", which is a boolean state that allows its user (i.e. GDB) to say "I'm doing a bunch of operations, you can hold off putting the threads on the GPU until I'm done" (the "forward progress not required" state). Turning forward progress back on indicates to the library that all threads that are supposed to be running should now be really running on the GPU. It turns out that GDB has a similar concept, though not as general, commit_resume. One difference is that commit_resume is not stateful: the target can't look up "does the core need me to schedule resumed threads for execution right now". It is also specifically linked to the resume method, it is not used in other contexts. The target accumulates resumption requests through target_ops::resume calls, and then commits those resumptions when target_ops::commit_resume is called. The target has no way to check if it's ok to leave resumed threads stopped in other target methods. To bridge the gap, this patch generalizes the commit_resume concept in GDB to match the forward progress concept of ROCdbgapi. The current name (commit_resume) can be interpreted as "commit the previous resume calls". I renamed the concept to "commit_resumed", as in "commit the threads that are resumed". In the new version, we have two things: - the commit_resumed_state field in process_stratum_target: indicates whether GDB requires target stacks using this target to have resumed threads committed to the execution target/device. If false, an execution target is allowed to leave resumed threads un-committed at the end of whatever method it is executing. - the commit_resumed target method: called when commit_resumed_state transitions from false to true. While commit_resumed_state was false, the target may have left some resumed threads un-committed. This method being called tells it that it should commit them back to the execution device. Let's take the "Stopping all threads" scenario from above and see how it would work with the ROCm target with this change. Before stopping all threads, GDB would set the target's commit_resumed_state field to false. It would then ask the target to stop the first thread. The target would retrieve all threads' state from the GPU and mark that one as stopped. Since commit_resumed_state is false, it leaves all the other threads (still resumed) stopped. GDB would then proceed to call target_stop for all the other threads. Since resumed threads are not committed, this doesn't do any back and forth with the GPU. To simplify the implementation of targets, this patch makes it so that when calling certain target methods, the contract between the core and the targets guarantees that commit_resumed_state is false. This way, the target doesn't need two paths, one for commit_resumed_state == true and one for commit_resumed_state == false. It can just assert that commit_resumed_state is false and work with that assumption. This also helps catch places where we forgot to disable commit_resumed_state before calling the method, which represents a probable optimization opportunity. The commit adds assertions in the target method wrappers (target_resume and friends) to have some confidence that this contract between the core and the targets is respected. The scoped_disable_commit_resumed type is used to disable the commit resumed state of all process targets on construction, and selectively re-enable it on destruction (see below for criteria). Note that it only sets the process_stratum_target::commit_resumed_state flag. A subsequent call to maybe_call_commit_resumed_all_targets is necessary to call the commit_resumed method on all target stacks with process targets that got their commit_resumed_state flag turned back on. This separation is because we don't want to call the commit_resumed methods in scoped_disable_commit_resumed's destructor, as they may throw. On destruction, commit-resumed is not re-enabled for a given target if: 1. this target has no threads resumed, or 2. this target has at least one resumed thread with a pending status known to the core (saved in thread_info::suspend::waitstatus). The first point is not technically necessary, because a proper commit_resumed implementation would be a no-op if the target has no resumed threads. But since we have a flag do to a quick check, it shouldn't hurt. The second point is more important: together with the scoped_disable_commit_resumed instance added in fetch_inferior_event, it makes it so the "Resuming with pending events" described above is handled efficiently. Here's what happens in that case: 1. The user types "continue". 2. Upon destruction, the scoped_disable_commit_resumed in the `proceed` function does not enable commit-resumed, as it sees some threads have pending statuses. 3. fetch_inferior_event is called to handle another event, the breakpoint hit evaluates to false, and that thread is resumed. Because there are still more threads with pending statuses, the destructor of scoped_disable_commit_resumed in fetch_inferior_event still doesn't enable commit-resumed. 4. Rinse and repeat step 3, until the last pending status is handled by fetch_inferior_event. In that case, scoped_disable_commit_resumed's destructor sees there are no more threads with pending statues, so it asks the target to commit resumed threads. This allows us to avoid all unnecessary back and forths, there is a single commit_resumed call once all pending statuses are processed. This change required remote_target::remote_stop_ns to learn how to handle stopping threads that were resumed but pending vCont. The simplest example where that happens is when using the remote target in all-stop, but with "maint set target-non-stop on", to force it to operate in non-stop mode under the hood. If two threads hit a breakpoint at the same time, GDB will receive two stop replies. It will present the stop for one thread and save the other one in thread_info::suspend::waitstatus. Before this patch, when doing "continue", GDB first resumes the thread without a pending status: Sending packet: $vCont;c:p172651.172676#f3 It then consumes the pending status in the next fetch_inferior_event call: [infrun] do_target_wait_1: Using pending wait status status->kind = stopped, signal = GDB_SIGNAL_TRAP for Thread 1517137.1517137. [infrun] target_wait (-1.0.0, status) = [infrun] 1517137.1517137.0 [Thread 1517137.1517137], [infrun] status->kind = stopped, signal = GDB_SIGNAL_TRAP It then realizes it needs to stop all threads to present the stop, so stops the thread it just resumed: [infrun] stop_all_threads: Thread 1517137.1517137 not executing [infrun] stop_all_threads: Thread 1517137.1517174 executing, need stop remote_stop called Sending packet: $vCont;t:p172651.172676#04 This is an unnecessary resume/stop. With this patch, we don't commit resumed threads after proceeding, because of the pending status: [infrun] maybe_commit_resumed_all_process_targets: not requesting commit-resumed for target extended-remote, a thread has a pending waitstatus When GDB handles the pending status and stop_all_threads runs, we stop a resumed but pending vCont thread: remote_stop_ns: Enqueueing phony stop reply for thread pending vCont-resume (1520940, 1520976, 0) That thread was never actually resumed on the remote stub / gdbserver, so we shouldn't send a packet to the remote side asking to stop the thread. Note that there are paths that resume the target and then do a synchronous blocking wait, in sort of nested event loop, via wait_sync_command_done. For example, inferior function calls, or any run control command issued from a breakpoint command list. We handle that making wait_sync_command_one a "sync" point -- force forward progress, or IOW, force-enable commit-resumed state. gdb/ChangeLog: yyyy-mm-dd Simon Marchi <simon.marchi@efficios.com> Pedro Alves <pedro@palves.net> * infcmd.c (run_command_1, attach_command, detach_command) (interrupt_target_1): Use scoped_disable_commit_resumed. * infrun.c (do_target_resume): Remove target_commit_resume call. (commit_resume_all_targets): Remove. (maybe_set_commit_resumed_all_targets): New. (maybe_call_commit_resumed_all_targets): New. (enable_commit_resumed): New. (scoped_disable_commit_resumed::scoped_disable_commit_resumed) (scoped_disable_commit_resumed::~scoped_disable_commit_resumed) (scoped_disable_commit_resumed::reset) (scoped_disable_commit_resumed::reset_and_commit) (scoped_enable_commit_resumed::scoped_enable_commit_resumed) (scoped_enable_commit_resumed::~scoped_enable_commit_resumed): New. (proceed): Use scoped_disable_commit_resumed and maybe_call_commit_resumed_all_targets. (fetch_inferior_event): Use scoped_disable_commit_resumed. * infrun.h (struct scoped_disable_commit_resumed): New. (maybe_call_commit_resumed_all_process_targets): New. (struct scoped_enable_commit_resumed): New. * mi/mi-main.c (exec_continue): Use scoped_disable_commit_resumed. * process-stratum-target.h (class process_stratum_target): <commit_resumed_state>: New. * record-full.c (record_full_wait_1): Change commit_resumed_state around calling commit_resumed. * remote.c (class remote_target) <commit_resume>: Rename to... <commit_resumed>: ... this. (struct stop_reply): Move up. (remote_target::commit_resume): Rename to... (remote_target::commit_resumed): ... this. Check if there is any thread pending vCont resume. (remote_target::remote_stop_ns): Generate stop replies for resumed but pending vCont threads. (remote_target::wait_ns): Add gdb_assert. * target-delegates.c: Regenerate. * target.c (target_wait, target_resume): Assert that the current process_stratum target isn't in commit-resumed state. (defer_target_commit_resume): Remove. (target_commit_resume): Remove. (target_commit_resumed): New. (make_scoped_defer_target_commit_resume): Remove. (target_stop): Assert that the current process_stratum target isn't in commit-resumed state. * target.h (struct target_ops) <commit_resume>: Rename to ... <commit_resumed>: ... this. (target_commit_resume): Remove. (target_commit_resumed): New. (make_scoped_defer_target_commit_resume): Remove. * top.c (wait_sync_command_done): Use scoped_enable_commit_resumed. [1] https://github.com/ROCm-Developer-Tools/ROCgdb/ [2] https://github.com/ROCm-Developer-Tools/ROCdbgapi Change-Id: I836135531a29214b21695736deb0a81acf8cf566 |
||
|
e5b9b39f88 |
target_is_non_stop_p and sync targets
gdb.base/maint-target-async-off.exp fails if you test against gdbserver with "maint set target-non-stop on" forced. (gdb) run Starting program: build/gdb/testsuite/outputs/gdb.base/maint-target-async-off/maint-target-async-off Breakpoint 1, main () at src/gdb/testsuite/gdb.base/maint-target-async-off.c:21 21 return 0; (gdb) FAIL: gdb.base/maint-target-async-off.exp: continue until exit (timeout) Above, GDB just stopped listening to stdin. Basically, GDB assumes that a target working in non-stop mode operation also supports async mode; it's a requirement. GDB misbehaves badly otherwise, and even hits failed assertions. Fix this by making target_is_non_stop_p return false if async is off. gdb/ChangeLog: * target.c (target_always_non_stop_p): Also check whether the target can async. Change-Id: I7e52e1061396a5b9b02ada462f68a14b76d68974 |
||
|
bab287cdcf |
Avoid some pointer chasing in DWARF reader
I noticed a spot in the DWARF reader using "per_objfile->per_bfd", where a local per_bfd variable had already been created. Looking through the file, I found a number of such spots. This patch changes them to use the already-existing local, avoiding a bit of excess pointer chasing. gdb/ChangeLog 2021-03-26 Tom Tromey <tom@tromey.com> * dwarf2/read.c (dwarf2_read_debug_names) (dwarf2_build_psymtabs_hard, create_addrmap_from_aranges) (dw2_debug_names_iterator::next, create_type_unit_group): Simplify. |
||
|
eff4f69db4 |
Fix bkpt-other-inferior.exp race
When testing with "maint set target-non-stop on", gdb.server/bkpt-other-inferior.exp sometimes fails like so: (gdb) inferior 2 [Switching to inferior 2 [process 368191] (<noexec>)] [Switching to thread 2.1 (Thread 368191.368191)] [remote] Sending packet: $m7ffff7fd0100,1#5b [remote] Packet received: 48 [remote] Sending packet: $m7ffff7fd0100,1#5b [remote] Packet received: 48 [remote] Sending packet: $m7ffff7fd0100,9#63 [remote] Packet received: 4889e7e8e80c000049 #0 0x00007ffff7fd0100 in ?? () (gdb) PASS: gdb.server/bkpt-other-inferior.exp: inf 2: switch to inferior break -q main Breakpoint 2 at 0x1138: file /home/pedro/gdb/binutils-gdb/src/gdb/testsuite/gdb.server/server.c, line 21. (gdb) PASS: gdb.server/bkpt-other-inferior.exp: inf 2: set breakpoint delete breakpoints Delete all breakpoints? (y or n) y (gdb) [remote] wait: enter [remote] wait: exit FAIL: gdb.server/bkpt-other-inferior.exp: inf 2: delete all breakpoints in delete_breakpoints (timeout) ERROR: breakpoints not deleted Remote debugging from host ::1, port 55876 monitor exit The problem is here: (gdb) [remote] wait: enter The testcase isn't expecting any output after the prompt. Why is that "[remote] wait" output? What happens is that "delete breakpoints" queries the user, and `query` disables/reenables target async, which results in the remote target's async event handler ending up marked: (top-gdb) bt #0 mark_async_event_handler (async_handler_ptr=0x556bffffffff) at ../../src/gdb/async-event.c:295 #1 0x0000556bf71b711f in infrun_async (enable=1) at ../../src/gdb/infrun.c:119 #2 0x0000556bf7471387 in target_async (enable=1) at ../../src/gdb/target.c:3684 #3 0x0000556bf748a0bd in gdb_readline_wrapper_cleanup::~gdb_readline_wrapper_cleanup (this=0x7ffe3cf30eb0, __in_chrg=<optimized out>) at ../../src/gdb/top.c:1074 #4 0x0000556bf74874e2 in gdb_readline_wrapper (prompt=0x556bfa17da60 "Delete all breakpoints? (y or n) ") at ../../src/gdb/top.c:1096 #5 0x0000556bf75111c5 in defaulted_query(const char *, char, typedef __va_list_tag __va_list_tag *) (ctlstr=0x556bf7717f34 "Delete all breakpoints? ", defchar=0 '\000', args=0x7ffe3cf31020) at ../../src/gdb/utils.c:893 #6 0x0000556bf751166f in query (ctlstr=0x556bf7717f34 "Delete all breakpoints? ") at ../../src/gdb/utils.c:985 #7 0x0000556bf6f11404 in delete_command (arg=0x0, from_tty=1) at ../../src/gdb/breakpoint.c:13500 ... ... which then later results in a target_wait call: (top-gdb) bt #0 remote_target::wait_ns (this=0x7ffe3cf30f80, ptid=..., status=0xde530314f0802800, options=...) at ../../src/gdb/remote.c:7937 #1 0x0000556bf7369dcb in remote_target::wait (this=0x556bfa0b2180, ptid=..., status=0x7ffe3cf31568, options=...) at ../../src/gdb/remote.c:8173 #2 0x0000556bf745e527 in target_wait (ptid=..., status=0x7ffe3cf31568, options=...) at ../../src/gdb/target.c:2000 #3 0x0000556bf71be686 in do_target_wait_1 (inf=0x556bfa1573d0, ptid=..., status=0x7ffe3cf31568, options=...) at ../../src/gdb/infrun.c:3463 #4 0x0000556bf71be88b in <lambda(inferior*)>::operator()(inferior *) const (__closure=0x7ffe3cf31320, inf=0x556bfa1573d0) at ../../src/gdb/infrun.c:3526 #5 0x0000556bf71bebcd in do_target_wait (wait_ptid=..., ecs=0x7ffe3cf31540, options=...) at ../../src/gdb/infrun.c:3539 #6 0x0000556bf71bf97b in fetch_inferior_event () at ../../src/gdb/infrun.c:3879 #7 0x0000556bf71a27f8 in inferior_event_handler (event_type=INF_REG_EVENT) at ../../src/gdb/inf-loop.c:42 #8 0x0000556bf71cc8b7 in infrun_async_inferior_event_handler (data=0x0) at ../../src/gdb/infrun.c:9220 #9 0x0000556bf6ecb80f in check_async_event_handlers () at ../../src/gdb/async-event.c:327 #10 0x0000556bf76b011a in gdb_do_one_event () at ../../src/gdbsupport/event-loop.cc:216 ... ... which returns TARGET_WAITKIND_IGNORE. Fix this by only enabling remote output around setting the breakpoint. gdb/testsuite/ChangeLog: * gdb.server/bkpt-other-inferior.exp: Only enable remote output around setting the breakpoint. Change-Id: I2fd152fd9c46b1c5e7fa678cc4d4054dac0b2bd4 |
||
|
323fd5b9f9 |
Fix problem exposed by gdb.server/stop-reply-no-thread-multi.exp
Running gdb.server/stop-reply-no-thread-multi.exp with "maint set target-non-stop on" occasionally hit an internal error like this: ... continue Continuing. warning: multi-threaded target stopped without sending a thread-id, using first non-exited thread /home/pedro/gdb/binutils-gdb/src/gdb/inferior.c:291: internal-error: inferior* find_inferior_pid(process_stratum_target*, int): Assertion `pid != 0' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. This is a bug, please report it. FAIL: gdb.server/stop-reply-no-thread-multi.exp: to_disable=Tthread: continue until exit (GDB internal error) The backtrace looks like this: ... #5 0x0000560357b0879c in internal_error (file=0x560357be6c18 "/home/pedro/gdb/binutils-gdb/src/gdb/inferior.c", line=291, fmt=0x560357be6b21 "%s: Assertion `%s' failed.") at /home/pedro/gdb/binutils-gdb/src/gdbsupport/errors.cc:55 #6 0x000056035762061b in find_inferior_pid (targ=0x5603596e9560, pid=0) at /home/pedro/gdb/binutils-gdb/src/gdb/inferior.c:291 #7 0x00005603576206e6 in find_inferior_ptid (targ=0x5603596e9560, ptid=...) at /home/pedro/gdb/binutils-gdb/src/gdb/inferior.c:305 #8 0x00005603577d43ed in remote_target::check_pending_events_prevent_wildcard_vcont (this=0x5603596e9560, may_global_wildcard=0x7fff84fb05f0) at /home/pedro/gdb/binutils-gdb/src/gdb/remote.c:7215 #9 0x00005603577d2a9c in remote_target::commit_resumed (this=0x5603596e9560) at /home/pedro/gdb/binutils-gdb/src/gdb/remote.c:6680 ... pid is 0 in this case because the queued event is a process exit event with no pid associated: (top-gdb) p event->ws During symbol reading: .debug_line address at offset 0x563c9a is 0 [in module /home/pedro/gdb/binutils-gdb/build/gdb/gdb] $1 = {kind = TARGET_WAITKIND_EXITED, value = {integer = 0, sig = GDB_SIGNAL_0, related_pid = {m_pid = 0, m_lwp = 0, m_tid = 0}, execd_pathname = 0x0, syscall_number = 0}} (top-gdb) This fixes it, and adds a "maint set target-non-stop on/off" axis to the testcase. gdb/ChangeLog: * remote.c (remote_target::check_pending_events_prevent_wildcard_vcont): Check whether the event's ptid is not null_ptid before looking up the corresponding inferior. gdb/testsuite/ChangeLog: * gdb.server/stop-reply-no-thread-multi.exp (run_test): Add "target_non_stop" parameter and use it. (top level): Add "maint set target-non-stop on/off" testing axis. Change-Id: Ia30cf275305ee4dcbbd33f731534cd71d1550eaa |
||
|
d3cbca38df |
gdb/riscv: fix creating breakpoints at invalid addresses
To allow breakpoints to be created at invalid addresses,
target_read_code is used instead of read_code. This was fixed in
commit:
commit
|
||
|
328d42d87e |
gdb: remove current_top_target function
The current_top_target function is a hidden dependency on the current inferior. Since I'd like to slowly move towards reducing our dependency on the global current state, remove this function and make callers use current_inferior ()->top_target () There is no expected change in behavior, but this one step towards making those callers use the inferior from their context, rather than refer to the global current inferior. gdb/ChangeLog: * target.h (current_top_target): Remove, make callers use the current inferior instead. * target.c (current_top_target): Remove. Change-Id: Iccd457036f84466cdaa3865aa3f9339a24ea001d |
||
|
d777bf0df2 |
gdb: move all "current target" wrapper implementations to target.c
The following patch removes the current_top_target function, replacing uses with `current_inferior ()->top_target ()`. This is a problem for uses in target.h, because they don't have access to the current_inferior function and the inferior structure: target.h can't include inferior.h, otherwise that would make a cyclic inclusion. Avoid this by moving all implementations of the wrappers that call target methods with the current target to target.c. Many of them are changed from a macro to a function, which is an improvement for readability and debuggability, IMO. target_shortname and target_longname were not function-like macros, so a few adjustments are needed. gdb/ChangeLog: * target.h (target_shortname): Change to function declaration. (target_longname): Likewise. (target_attach_no_wait): Likewise. (target_post_attach): Likewise. (target_prepare_to_store): Likewise. (target_supports_enable_disable_tracepoint): Likewise. (target_supports_string_tracing): Likewise. (target_supports_evaluation_of_breakpoint_conditions): Likewise. (target_supports_dumpcore): Likewise. (target_dumpcore): Likewise. (target_can_run_breakpoint_commands): Likewise. (target_files_info): Likewise. (target_post_startup_inferior): Likewise. (target_insert_fork_catchpoint): Likewise. (target_remove_fork_catchpoint): Likewise. (target_insert_vfork_catchpoint): Likewise. (target_remove_vfork_catchpoint): Likewise. (target_insert_exec_catchpoint): Likewise. (target_remove_exec_catchpoint): Likewise. (target_set_syscall_catchpoint): Likewise. (target_rcmd): Likewise. (target_can_lock_scheduler): Likewise. (target_can_async_p): Likewise. (target_is_async_p): Likewise. (target_execution_direction): Likewise. (target_extra_thread_info): Likewise. (target_pid_to_exec_file): Likewise. (target_thread_architecture): Likewise. (target_find_memory_regions): Likewise. (target_make_corefile_notes): Likewise. (target_get_bookmark): Likewise. (target_goto_bookmark): Likewise. (target_stopped_by_watchpoint): Likewise. (target_stopped_by_sw_breakpoint): Likewise. (target_supports_stopped_by_sw_breakpoint): Likewise. (target_stopped_by_hw_breakpoint): Likewise. (target_supports_stopped_by_hw_breakpoint): Likewise. (target_have_steppable_watchpoint): Likewise. (target_can_use_hardware_watchpoint): Likewise. (target_region_ok_for_hw_watchpoint): Likewise. (target_can_do_single_step): Likewise. (target_insert_watchpoint): Likewise. (target_remove_watchpoint): Likewise. (target_insert_hw_breakpoint): Likewise. (target_remove_hw_breakpoint): Likewise. (target_can_accel_watchpoint_condition): Likewise. (target_can_execute_reverse): Likewise. (target_get_ada_task_ptid): Likewise. (target_filesystem_is_local): Likewise. (target_trace_init): Likewise. (target_download_tracepoint): Likewise. (target_can_download_tracepoint): Likewise. (target_download_trace_state_variable): Likewise. (target_enable_tracepoint): Likewise. (target_disable_tracepoint): Likewise. (target_trace_start): Likewise. (target_trace_set_readonly_regions): Likewise. (target_get_trace_status): Likewise. (target_get_tracepoint_status): Likewise. (target_trace_stop): Likewise. (target_trace_find): Likewise. (target_get_trace_state_variable_value): Likewise. (target_save_trace_data): Likewise. (target_upload_tracepoints): Likewise. (target_upload_trace_state_variables): Likewise. (target_get_raw_trace_data): Likewise. (target_get_min_fast_tracepoint_insn_len): Likewise. (target_set_disconnected_tracing): Likewise. (target_set_circular_trace_buffer): Likewise. (target_set_trace_buffer_size): Likewise. (target_set_trace_notes): Likewise. (target_get_tib_address): Likewise. (target_set_permissions): Likewise. (target_static_tracepoint_marker_at): Likewise. (target_static_tracepoint_markers_by_strid): Likewise. (target_traceframe_info): Likewise. (target_use_agent): Likewise. (target_can_use_agent): Likewise. (target_augmented_libraries_svr4_read): Likewise. (target_log_command): Likewise. * target.c (target_shortname): New. (target_longname): New. (target_attach_no_wait): New. (target_post_attach): New. (target_prepare_to_store): New. (target_supports_enable_disable_tracepoint): New. (target_supports_string_tracing): New. (target_supports_evaluation_of_breakpoint_conditions): New. (target_supports_dumpcore): New. (target_dumpcore): New. (target_can_run_breakpoint_commands): New. (target_files_info): New. (target_post_startup_inferior): New. (target_insert_fork_catchpoint): New. (target_remove_fork_catchpoint): New. (target_insert_vfork_catchpoint): New. (target_remove_vfork_catchpoint): New. (target_insert_exec_catchpoint): New. (target_remove_exec_catchpoint): New. (target_set_syscall_catchpoint): New. (target_rcmd): New. (target_can_lock_scheduler): New. (target_can_async_p): New. (target_is_async_p): New. (target_execution_direction): New. (target_extra_thread_info): New. (target_pid_to_exec_file): New. (target_thread_architecture): New. (target_find_memory_regions): New. (target_make_corefile_notes): New. (target_get_bookmark): New. (target_goto_bookmark): New. (target_stopped_by_watchpoint): New. (target_stopped_by_sw_breakpoint): New. (target_supports_stopped_by_sw_breakpoint): New. (target_stopped_by_hw_breakpoint): New. (target_supports_stopped_by_hw_breakpoint): New. (target_have_steppable_watchpoint): New. (target_can_use_hardware_watchpoint): New. (target_region_ok_for_hw_watchpoint): New. (target_can_do_single_step): New. (target_insert_watchpoint): New. (target_remove_watchpoint): New. (target_insert_hw_breakpoint): New. (target_remove_hw_breakpoint): New. (target_can_accel_watchpoint_condition): New. (target_can_execute_reverse): New. (target_get_ada_task_ptid): New. (target_filesystem_is_local): New. (target_trace_init): New. (target_download_tracepoint): New. (target_can_download_tracepoint): New. (target_download_trace_state_variable): New. (target_enable_tracepoint): New. (target_disable_tracepoint): New. (target_trace_start): New. (target_trace_set_readonly_regions): New. (target_get_trace_status): New. (target_get_tracepoint_status): New. (target_trace_stop): New. (target_trace_find): New. (target_get_trace_state_variable_value): New. (target_save_trace_data): New. (target_upload_tracepoints): New. (target_upload_trace_state_variables): New. (target_get_raw_trace_data): New. (target_get_min_fast_tracepoint_insn_len): New. (target_set_disconnected_tracing): New. (target_set_circular_trace_buffer): New. (target_set_trace_buffer_size): New. (target_set_trace_notes): New. (target_get_tib_address): New. (target_set_permissions): New. (target_static_tracepoint_marker_at): New. (target_static_tracepoint_markers_by_strid): New. (target_traceframe_info): New. (target_use_agent): New. (target_can_use_agent): New. (target_augmented_libraries_svr4_read): New. (target_log_command): New. * bfin-tdep.c (bfin_sw_breakpoint_from_kind): Adjust. * infrun.c (set_schedlock_func): Adjust. * mi/mi-main.c (exec_reverse_continue): Adjust. * reverse.c (exec_reverse_once): Adjust. * sh-tdep.c (sh_sw_breakpoint_from_kind): Adjust. * tui/tui-stack.c (tui_locator_window::make_status_line): Adjust. * remote-sim.c (gdbsim_target::detach): Adjust. (gdbsim_target::files_info): Adjust. Change-Id: I72ef56e9a25adeb0b91f1ad05e34c89f77ebeaa8 |
||
|
b64f703b51 |
Remove 'kind' parameter from dw2_map_matching_symbols
I noticed that dw2_map_matching_symbols does not use its 'kind' parameter. This patch removes it. Tested by rebuilding. 2021-03-24 Tom Tromey <tom@tromey.com> * dwarf2/read.c (dw2_map_matching_symbols): Update. (dw2_expand_symtabs_matching_symbol): Remove 'kind' parameter. (check_match, dw2_expand_symtabs_matching) (dwarf2_debug_names_index::map_matching_symbols) (dwarf2_debug_names_index::expand_symtabs_matching): Update. |
||
|
68f115f8c0 |
Fix TYPE_DECLARED_CLASS thinko
Simon pointed out an error that I made in compile_cplus_conver_struct_or_union in my original C++ compile submission: if (type->code () == TYPE_CODE_STRUCT) { const char *what = TYPE_DECLARED_CLASS (type) ? "struct" : "class"; resuld = instance->plugin ().build_decl (what, name.get (), (GCC_CP_SYMBOL_CLASS | nested_access | (TYPE_DECLARED_CLASS (type) ? GCC_CP_FLAG_CLASS_NOFLAG : GCC_CP_FLAG_CLASS_IS_STRUCT)), 0, nullptr, 0, filename, line); } Notice that WHAT will contain "struct" for TYPE_DECLARED_CLASS. Whoops. Fortunately this first parameter of build_decl is only used for debugging. gdb/ChangeLog 2021-03-24 Keith Seitz <keiths@redhat.com> * compile/compile-cplus-types.c (compile_cplus_convert_struct_or_union): Fix TYPE_DECLARED_CLASS thinko. |
||
|
41c0087ba5 |
gdb: make gdbarch_data_registry static
This variable was made static in:
|