Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

expressions fail when calling varargs functions on FreeBSD 9.2 (built with GCC 4.2.1) #17557

Closed
emaste opened this issue Sep 10, 2013 · 10 comments
Assignees
Labels
bugzilla Issues migrated from bugzilla lldb

Comments

@emaste
Copy link
Member

emaste commented Sep 10, 2013

Bugzilla Link 17183
Resolution FIXED
Resolved on Feb 24, 2014 13:27
Version unspecified
OS FreeBSD

Extended Description

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 *)

@emaste
Copy link
Member Author

emaste commented Sep 10, 2013

assigned to @emaste

@emaste
Copy link
Member Author

emaste commented Nov 13, 2013

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.

@emaste
Copy link
Member Author

emaste commented Feb 22, 2014

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

@llvmbot
Copy link
Collaborator

llvmbot commented Feb 22, 2014

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.

@llvmbot
Copy link
Collaborator

llvmbot commented Feb 22, 2014

Looks like you need to attach the ELF file for libc.so.7 that contains the DWARF debug info.

@emaste
Copy link
Member Author

emaste commented Feb 22, 2014

vararg test
vararg demo

@emaste
Copy link
Member Author

emaste commented Feb 22, 2014

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) 2014021
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.

@llvmbot
Copy link
Collaborator

llvmbot commented Feb 24, 2014

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.

@emaste
Copy link
Member Author

emaste commented Feb 24, 2014

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

@emaste
Copy link
Member Author

emaste commented Feb 24, 2014

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 9, 2021
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla lldb
Projects
None yet
Development

No branches or pull requests

2 participants