LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 17183 - expressions fail when calling varargs functions on FreeBSD 9.2 (built with GCC 4.2.1)
Summary: expressions fail when calling varargs functions on FreeBSD 9.2 (built with GC...
Status: RESOLVED FIXED
Alias: None
Product: lldb
Classification: Unclassified
Component: All Bugs (show other bugs)
Version: unspecified
Hardware: PC FreeBSD
: P normal
Assignee: emaste
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-09-10 10:59 PDT by emaste
Modified: 2014-02-24 13:27 PST (History)
1 user (show)

See Also:
Fixed By Commit(s):


Attachments
vararg test (263 bytes, text/x-csrc)
2014-02-21 18:56 PST, emaste
Details

Note You need to log in before you can comment on or make changes to this bug.
Description emaste 2013-09-10 10:59:13 PDT
Test fails on FreeBSD: test/expression_command/radar_9531204/TestPrintfAfterUp.py

Reproducing manually:

(lldb) expression (int)printf("value is %d.\\n", value);
error: no matching function for call to 'printf'
note: candidate function not viable: requires 1 argument, but 2 were provided
error: 1 errors parsing expression

turning on expression logging shows

ClangExpressionDeclMap::FindExternalVisibleDecls[6] for 'printf' in a 'TranslationUnit'
  CEDM::FEVD[6] Searching the root namespace
  CEDM::FEVD[6] Found specific function printf (description libc.so.7`printf at printf.c:50), returned static int printf(static const char *)
Comment 1 emaste 2013-11-13 12:59:03 PST
This is on FreeBSD 9.2, with libc.so built with the default system compiler GCC 4.2.1.  I suspect this is an issue with the DWARF generated by that old GCC and that newer GCC or clang will not demonstrate this problem.
Comment 2 emaste 2014-02-21 16:11:36 PST
A related failure is that I'm seeing on my FreeBSD 9.2 test system is test/expression_command/test/TestExprs.py, also a failing printf expression:

(lldb) expr printf("\t\x68\n")
error: Execution was interrupted, reason: invalid address (fault address: 0xfffffffffffffffe).
The process has been returned to the state before expression evaluation.

The expression parser produces:

Function disassembly:
0x8007d9010:  55                             pushq  %rbp
0x8007d9011:  48 89 e5                       movq   %rsp, %rbp
0x8007d9014:  41 57                          pushq  %r15
0x8007d9016:  41 56                          pushq  %r14
0x8007d9018:  41 54                          pushq  %r12
0x8007d901a:  53                             pushq  %rbx
0x8007d901b:  48 83 ec 10                    subq   $0x10, %rsp
0x8007d901f:  48 89 fb                       movq   %rdi, %rbx
0x8007d9022:  49 bf 00 90 7d 00 08 00 00 00  movabsq $0x8007d9000, %r15
0x8007d902c:  45 31 e4                       xorl   %r12d, %r12d
0x8007d902f:  31 c0                          xorl   %eax, %eax
0x8007d9031:  41 ff d7                       callq  *%r15
0x8007d9034:  4c 8b 33                       movq   (%rbx), %r14
0x8007d9037:  48 8d 7d d8                    leaq   -0x28(%rbp), %rdi
0x8007d903b:  31 c0                          xorl   %eax, %eax
0x8007d903d:  41 ff d7                       callq  *%r15
0x8007d9040:  48 89 5d d8                    movq   %rbx, -0x28(%rbp)
0x8007d9044:  45 84 e4                       testb  %r12b, %r12b
0x8007d9047:  75 20                          jne    0x8007d9069
0x8007d9049:  49 8d 87 50 09 65 00           leaq   0x650950(%r15), %rax
0x8007d9050:  48 bf 00 80 7d 00 08 00 00 00  movabsq $0x8007d8000, %rdi
0x8007d905a:  ff d0                          callq  *%rax
0x8007d905c:  89 c3                          movl   %eax, %ebx
0x8007d905e:  31 c0                          xorl   %eax, %eax
0x8007d9060:  4c 89 f7                       movq   %r14, %rdi
0x8007d9063:  41 ff d7                       callq  *%r15
0x8007d9066:  41 89 1e                       movl   %ebx, (%r14)
0x8007d9069:  48 83 c4 10                    addq   $0x10, %rsp
0x8007d906d:  5b                             popq   %rbx
0x8007d906e:  41 5c                          popq   %r12
0x8007d9070:  41 5e                          popq   %r14
0x8007d9072:  41 5f                          popq   %r15
0x8007d9074:  5d                             popq   %rbp
0x8007d9075:  c3                             retq   

without detecting printf as a varargs function it can't be called correctly
Comment 3 Greg Clayton 2014-02-21 16:29:15 PST
Ed: I would check your DWARF for debug info for "printf". If there is a function prototype, LLDB could either be parsing it wrong, or it might be wrong in the DWARF. If you can attach the executable that contains the DWARF for "printf", I can probably tell you more.
Comment 4 Greg Clayton 2014-02-21 16:30:14 PST
Looks like you  need to attach the ELF file for libc.so.7 that contains the DWARF debug  info.
Comment 5 emaste 2014-02-21 18:56:26 PST
Created attachment 12107 [details]
vararg test

vararg demo
Comment 6 emaste 2014-02-21 19:05:35 PST
It looks like there is more to this issue than I thought.  Simple varargs test attached.

Building with the system compiler on my laptop, FreeBSD 11-CURRENT / clang 3.4 gives me:

joule% cc --version
FreeBSD clang version 3.4 (tags/RELEASE_34/final 197956) 20140216
Target: x86_64-unknown-freebsd11.0
Thread model: posix
joule% cc -g -Wall vararg.c
joule% readelf -a a.out
...
< 1><0x00000026>    DW_TAG_subprogram
                      DW_AT_name                  sum
                      DW_AT_decl_file             0x00000001 /tank/emaste/src/snippets/vararg.c
                      DW_AT_decl_line             0x00000004
                      DW_AT_prototyped            yes(1)
                      DW_AT_type                  <0x0000007c>
                      DW_AT_external              yes(1)
                      DW_AT_low_pc                0x004006f0
                      DW_AT_high_pc               0x004008ee
                      DW_AT_frame_base            DW_OP_reg6
< 2><0x00000043>      DW_TAG_formal_parameter
                        DW_AT_name                  count
                        DW_AT_decl_file             0x00000001 /tank/emaste/src/snippets/vararg.c
                        DW_AT_decl_line             0x00000004
                        DW_AT_type                  <0x0000007c>
                        DW_AT_location              DW_OP_fbreg -4
< 2><0x00000051>      DW_TAG_variable
                        DW_AT_name                  ap
                        DW_AT_decl_file             0x00000001 /tank/emaste/src/snippets/vararg.c
                        DW_AT_decl_line             0x00000006
                        DW_AT_type                  <0x000000cb>
                        DW_AT_location              DW_OP_fbreg -32
< 2><0x0000005f>      DW_TAG_variable
                        DW_AT_name                  i
                        DW_AT_decl_file             0x00000001 /tank/emaste/src/snippets/vararg.c
                        DW_AT_decl_line             0x00000007
                        DW_AT_type                  <0x0000007c>
                        DW_AT_location              DW_OP_fbreg -36
< 2><0x0000006d>      DW_TAG_variable
                        DW_AT_name                  sum
                        DW_AT_decl_file             0x00000001 /tank/emaste/src/snippets/vararg.c
                        DW_AT_decl_line             0x00000007
                        DW_AT_type                  <0x0000007c>
                        DW_AT_location              DW_OP_fbreg -40
< 1><0x0000007c>    DW_TAG_base_type
                      DW_AT_name                  int
                      DW_AT_encoding              DW_ATE_signed
                      DW_AT_byte_size             0x00000004
...

(lldb) expr sum(2, 1, 1)
error: no matching function for call to 'sum'
note: candidate function not viable: requires 1 argument, but 3 were provided
error: 1 errors parsing expression

DWARF output from our old GCC is somewhat different:
joule% gcc --version        
gcc (GCC) 4.2.1 20070831 patched [FreeBSD]
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

joule% gcc -g -Wall vararg.c
dwarfdump -a a.out
...
< 1><0x000001a9>    DW_TAG_subprogram
                      DW_AT_external              yes(1)
                      DW_AT_name                  sum
                      DW_AT_decl_file             0x00000001 /tank/emaste/src/snippets/vararg.c
                      DW_AT_decl_line             0x00000005
                      DW_AT_prototyped            yes(1)
                      DW_AT_type                  <0x000000ae>
                      DW_AT_low_pc                0x004006f0
                      DW_AT_high_pc               0x00400845
                      DW_AT_frame_base            <loclist with 3 entries follows>
                        [ 0]<lowpc=0x00000000><highpc=0x00000001>DW_OP_breg7+8
                        [ 1]<lowpc=0x00000001><highpc=0x00000004>DW_OP_breg7+16
                        [ 2]<lowpc=0x00000004><highpc=0x00000155>DW_OP_breg6+16
                      DW_AT_sibling               <0x0000020b>
< 2><0x000001ce>      DW_TAG_formal_parameter
                        DW_AT_name                  count
                        DW_AT_decl_file             0x00000001 /tank/emaste/src/snippets/vararg.c
                        DW_AT_decl_line             0x00000004
                        DW_AT_type                  <0x000000ae>
                        DW_AT_location              DW_OP_fbreg -228
< 2><0x000001df>      DW_TAG_unspecified_parameters
< 2><0x000001e0>      DW_TAG_variable
                        DW_AT_name                  ap
                        DW_AT_decl_file             0x00000001 /tank/emaste/src/snippets/vararg.c
                        DW_AT_decl_line             0x00000006
                        DW_AT_type                  <0x0000019a>
                        DW_AT_location              DW_OP_fbreg -224
< 2><0x000001ee>      DW_TAG_variable
                        DW_AT_name                  i
                        DW_AT_decl_file             0x00000001 /tank/emaste/src/snippets/vararg.c
                        DW_AT_decl_line             0x00000007
                        DW_AT_type                  <0x000000ae>
                        DW_AT_location              DW_OP_fbreg -200
< 2><0x000001fb>      DW_TAG_variable
                        DW_AT_name                  sum
                        DW_AT_decl_file             0x00000001 /tank/emaste/src/snippets/vararg.c
                        DW_AT_decl_line             0x00000007
                        DW_AT_type                  <0x000000ae>
                        DW_AT_location              DW_OP_fbreg -196
...

Looks like DW_TAG_unspecified_parameters should report that this is a vararg fn, but lldb reports the same error for this case.
Comment 7 Greg Clayton 2014-02-24 13:12:52 PST
This is a clang bug. It should be emitting a DW_TAG_unspecified_parameters tag after the DW_TAG_formal_parameter children in a DW_TAG_subprogram, DW_TAG_inlined_subroutine, or DW_TAG_subroutine_type.

There is a long standing bug tracking this in clang at apple: 13690847

If you file a bug on Bugzilla, you should reference the apple bug number.

I fixed LLDB to be ready for the clang change with:

% svn commit source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
Sending        source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
Sending        source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
Transmitting file data ..
Committed revision 202061.

So now if you file a bugzilla bug on clang, you can track when it gets fixed on the clang side. Marking as fixed because LLDB is ready for the clang changes.
Comment 8 emaste 2014-02-24 13:20:17 PST
Works w/ gcc after r202061 (http://llvm.org/viewvc/llvm-project?rev=202061&view=rev)

Unfortunately Clang does not (yet) emit DW_TAG_unspecified_parameters, so still fails when built w/ Clang
Comment 9 emaste 2014-02-24 13:27:06 PST
Clang bug: http://llvm.org/bugs/show_bug.cgi?id=18950