GDB: Work around buggy Dwarf lineinfo produced by third party compiler.
Commit Message
* gdb/dwarf2read.c (producer_is_codewarrior): New function.
* gdb/dwarf2read.c (lnp_state_machine::record_line): Ignore is_stmt
flag for records produced by codewarrior.
---
gdb/dwarf2read.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
Comments
On 2018-10-03 4:49 a.m., John Darrington wrote:
> * gdb/dwarf2read.c (producer_is_codewarrior): New function.
> * gdb/dwarf2read.c (lnp_state_machine::record_line): Ignore is_stmt
> flag for records produced by codewarrior.
Hi John,
The code looks good to me, but could you mention (both in the commit log and the
code) what compiler version you are using? If somebody comes up later and says
this workaround breaks their debugging of codewarrior-generated code, we'll have
a bit of data to sort it out.
I think we've talked about it on IRC, but if I understand correctly, this is not
a maintained product anymore, so there's no use of notifying the publisher so they
fix the problem in the compiler?
On nit, you could use "bool" as a return type for producer_is_codewarrior (the other
producer_is_* functions were written pre-switch-to-C++).
For the ChangeLog, the paths should be relative to the ChangeLog (gdb/ChangeLog)
in this case, so you would remove the leading gdb/. Also, you would not repeat
the same filename, just put the entries in the same file after. Finally, there
are some entries missing. Overall, it could look like this:
* dwarf2read.c (dwarf2_cu) <producer_is_codewarrior>: New field.
(check_producer): Check if the producer is codewarrior.
(producer_is_codewarrior): New function.
(lnp_state_machine::record_line): Ignore is_stmt flag for records
produced by codewarrior.
(dwarf2_cu::dwarf2_cu): Initialize producer_is_codewarrior.
Thanks,
Simon
@@ -552,6 +552,7 @@ struct dwarf2_cu
unsigned int producer_is_gxx_lt_4_6 : 1;
unsigned int producer_is_gcc_lt_4_3 : 1;
unsigned int producer_is_icc_lt_14 : 1;
+ unsigned int producer_is_codewarrior : 1;
/* When set, the file that we're processing is known to have
debugging info for C++ namespaces. GCC 3.3.x did not produce
@@ -14903,6 +14904,8 @@ check_producer (struct dwarf2_cu *cu)
}
else if (producer_is_icc (cu->producer, &major, &minor))
cu->producer_is_icc_lt_14 = major < 14;
+ else if (startswith (cu->producer, "CodeWarrior S12/L-ISA"))
+ cu->producer_is_codewarrior = true;
else
{
/* For other non-GCC compilers, expect their behavior is DWARF version
@@ -14925,6 +14928,19 @@ producer_is_gxx_lt_4_6 (struct dwarf2_cu *cu)
return cu->producer_is_gxx_lt_4_6;
}
+
+/* Codewarrior generates dwarf line information with incorrect is_stmt
+ attributes. */
+
+static int
+producer_is_codewarrior (struct dwarf2_cu *cu)
+{
+ if (!cu->checked_producer)
+ check_producer (cu);
+
+ return cu->producer_is_codewarrior;
+}
+
/* Return the default accessibility type if it is not overriden by
DW_AT_accessibility. */
@@ -20789,7 +20805,7 @@ lnp_state_machine::record_line (bool end_sequence)
else if (m_op_index == 0 || end_sequence)
{
fe->included_p = 1;
- if (m_record_lines_p && m_is_stmt)
+ if (m_record_lines_p && (producer_is_codewarrior (m_cu) || m_is_stmt))
{
if (m_last_subfile != m_cu->builder->get_current_subfile ()
|| end_sequence)
@@ -25120,6 +25136,7 @@ dwarf2_cu::dwarf2_cu (struct dwarf2_per_cu_data *per_cu_)
producer_is_gxx_lt_4_6 (0),
producer_is_gcc_lt_4_3 (0),
producer_is_icc_lt_14 (0),
+ producer_is_codewarrior (0),
processing_has_namespace_info (0)
{
per_cu->cu = this;