[llvm-bugs] [Bug 38952] New: [DebugInfo at O2][Dexter] Bad value reported for function argument

via llvm-bugs llvm-bugs at lists.llvm.org
Fri Sep 14 08:13:26 PDT 2018


https://bugs.llvm.org/show_bug.cgi?id=38952

            Bug ID: 38952
           Summary: [DebugInfo at O2][Dexter] Bad value reported for function
                    argument
           Product: new-bugs
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Keywords: wrong-debug
          Severity: normal
          Priority: P
         Component: new bugs
          Assignee: unassignedbugs at nondot.org
          Reporter: jeremy.morse.llvm at gmail.com
                CC: chackz0x12 at gmail.com, greg.bedwell at sony.com,
                    international.phantom at gmail.com,
                    llvm-bugs at lists.llvm.org, paul.robinson at am.sony.com
            Blocks: 38768

The trivial program below causes an incorrect value of 'argc' to be reported to
debuggers, when optimised, compiled "-O2 -g -fno-inline" with llvm/clang
r341546 targeting x86_64.

Pretty simply, when launched in gdb or lldb, the first line of 'main' will
report that 'argc' has the value zero, when in truth it's one. [Note that the
value of argc changes depending on what you pass on the command line, but it
should always be at least one with no arguments].

-------->8--------
#include <string.h>

#define BUFSZ 256

int foo[BUFSZ];

int
main(int argc, char **argv)
{
  if (argc + 1 > BUFSZ)
    return 0;

  memset(foo, 0, argc * sizeof(int));

  return foo[argc / 2];
}
--------8<--------

Looking at the location-data for 'argc' and the first few instructions of the
program, when compiled with the options above:

llvm-dwarfdump-6.0 a.out --name=argc:
-------->8--------
0x00000073: DW_TAG_formal_parameter
              DW_AT_location    (0x00000000
                 0x0000000000000000 - 0x0000000000000003: DW_OP_reg5 RDI
                 0x0000000000000003 - 0x000000000000000d: DW_OP_reg3 RBX)
--------8<--------

Disassembly in gdb, having run "start" then "disassemble":
-------->8--------
Dump of assembler code for function main(int, char**):
   0x0000000000400500 <+0>:     push   %rbx
   0x0000000000400501 <+1>:     xor    %eax,%eax
=> 0x0000000000400503 <+3>:     cmp    $0xff,%edi
   0x0000000000400509 <+9>:     jg     0x400532 <main(int, char**)+50>
   0x000000000040050b <+11>:    mov    %edi,%ebx
--------8<--------

In the disassembly, the mov at +0xb stashes argc to %ebx to save it over the
call to memset. The location data believes this is happening earlier, at +0x3,
and as a result the as-yet-unwritten contents of %ebx are reported as the value
of argc.

Removing either the memset call, or the conditional statement, eliminates this
problem. It's also mildly annoying that 'argc' isn't defined over more of the
body of the program, despite being in a register the whole time, but that's for
a different ticket. In case this was duplicate of another SimplifyCFG bug I've
tried compiling with Carlos' latest patch from https://reviews.llvm.org/D51976
(165505) but that didn't make a difference.

This problem doesn't occur with clang-6.0 installed on Ubuntu 18, I don't have
clang-7.0 builds handy.


Referenced Bugs:

https://bugs.llvm.org/show_bug.cgi?id=38768
[Bug 38768] [meta][DebugInfo] Umbrella bug for poor debug experiences
-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20180914/bf336172/attachment.html>


More information about the llvm-bugs mailing list