New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 719020 link

Starred by 1 user

Issue metadata

Status: Verified
Owner:
Closed: May 2017
Cc:
EstimatedDays: ----
NextAction: ----
OS: Chrome
Pri: 2
Type: Bug



Sign in to add a comment

x86_64-cros-linux-gnu-clang generates wrong debug info

Project Member Reported by rahulchaudhry@chromium.org, May 5 2017

Issue description

$ cat rp.c 
#include <stdlib.h>

__typeof__(realpath) *rp;

int main(void)
{
        return 0;
}

$ for cc in "clang" "x86_64-cros-linux-gnu-clang"
do
        echo "Testing $cc"
        $cc -g -O2 rp.c
        echo "whatis rp" | gdb -q a.out
        echo
        rm -f a.out
done

Testing clang
Reading symbols from a.out...done.
(gdb) type = char *(*)(const char * restrict, char * restrict)
(gdb) quit

Testing x86_64-cros-linux-gnu-clang
Reading symbols from a.out...done.
(gdb) type = char *(**)(const char * restrict, char * restrict)
(gdb) quit


In the debug info generated by "x86_64-cros-linux-gnu-clang -g -O2", there's an extra indirection in the type for symbol "realpath".

Plain "clang" generates the correct debug info. So do "gcc" and "x86_64-cros-linux-gnu-gcc".
"x86_64-cros-linux-gnu-clang -g" (without -O2) also generates the correct debug info.

 
That's interesting. But cros-clang goes through the wrapper which adds some flags. What is clang behavior when same flags are passed to clang?
Yes, I'm guessing it has something to do with the flags we add, especially the ones related to FORTIFY, as that enables some macros which seem to modify function declarations in header files.

Blocking: 674175
Blocking: -674175

Comment 5 by lloz...@google.com, May 8 2017

any more info about this? 
how did you find this issue?

Discovered this while working on https://chromium-review.googlesource.com/#/c/498147 to make dev-lang/go work seamlessly with CC set to clang.

There is a new package in the go1.8 standard library that calls the C realpath() function using Cgo.
One of the ways Cgo figures out the types of C identifiers is to create a small stub program using the identifier, compiling it with the C compiler (with -g) and then reading the dwarf debug info for the identifier. This flow breaks down when using "x86_64-cros-linux-gnu-clang" or "armv7a-cros-linux-gnueabi-clang" as the generated debug info is incorrect.

Comment 7 by lloz...@google.com, May 8 2017

can you try without the FORTIFY define?

Comment 8 by g...@chromium.org, May 8 2017

Cc: g...@chromium.org
I've verified that setting _FORTIFY_SOURCE to "1" or "2" results in the incorrect debug info:

$ for i in 0 1 2; do clang -D_FORTIFY_SOURCE=$i -g -O2 rp.c && echo "whatis rp" | gdb -q a.out; done
Reading symbols from a.out...done.
(gdb) type = char *(*)(const char * restrict, char * restrict)
(gdb) quit
Reading symbols from a.out...done.
(gdb) type = char *(**)(const char * restrict, char * restrict)
(gdb) quit
Reading symbols from a.out...done.
(gdb) type = char *(**)(const char * restrict, char * restrict)
(gdb) quit

The testcase "rp.c" is same as in the original bug report.
All three invocations are running the plain "clang" here (not through the sysroot_wrapper like "x86_64-cros-linux-gnu-clang" and "armv7a-cros-linux-gnueabi-clang" do).

Comment 10 by g...@chromium.org, May 8 2017

Owner: g...@chromium.org
i'll see if i can track down what's causing this, then.

thanks for the report!

Comment 11 by g...@chromium.org, May 9 2017

the core issue here was that, if `foo` was overloaded and only one overload could have its address taken, we treat `__typeof__(foo)` as though the user had written `__typeof__(&foo)`. fix will find its way upstream shortly.

will we need to cherrypick that fix, or can we wait for it to land in ChromeOS naturally?

(as you've probably already figured out, the workaround is to just -U_FORTIFY_SOURCE. since the un-FORTIFYed file is apparently only useful for its debug info, whether or not it's FORTIFYed presumably doesn't matter at all)

Comment 12 by g...@chromium.org, May 9 2017

Status: Fixed (was: Untriaged)
fixed in r302506. please let me know if you'd like me to cherrypick :)
if the fix is simple, let's cherry pick it.

I am not sure if this will affect the quality of crash dumps. 

 
I have a CL blocking on this bug for switching dev-lang/go to use clang (https://chromium-review.googlesource.com/#/c/498147), but that can wait until we update clang on the regular schedule.
I'm fine with dev-lang/go staying on gcc until then.
Please ping this bug (or the CL) when the fix arrives in chromiumos toolchains.

However, there are other packages (all of them?) that compile with "-O2 -D_FORTIFY_SOURCE=2", and this bug could be effecting the debug info for those, which we won't know about until someone tries to debug a crash from the field (we should probably have local unit tests for this stuff, both in llvm/clang and in chromiumos).
Status: Assigned (was: Fixed)
On that note, I think it is reasonable to keep the bug open until the fix actually lands in chromiumos toolchains.

Cc: pirama@google.com chh@google.com yikong@google.com srhines@google.com

Comment 17 by g...@chromium.org, May 9 2017

> there are other packages (all of them?) that compile with "-O2 -D_FORTIFY_SOURCE=2", and this bug could be effecting the debug info for those, which we won't know about until someone tries to debug a crash from the field

FWIW, this bug wasn't in debuginfo emission; clang inferred a different type for `typeof(foo)` if foo was an overloaded function that had the right set of attributes on it.

(i'm not disagreeing with you; i'm just saying that the problem, if hit, will probably also show up as a compile-time error or a warning about an invalid pointer conversion. :) )

cherrypick coming soon.
Ahh.. I see. It's much lower severity then. Sorry I missed that.

Indeed, my testcase (and the one used by Cgo) only declares the variable for inspecting the debug info. It never uses the variable. Any use will have caused a compile time error.

Comment 19 by g...@chromium.org, May 10 2017

> It's much lower severity then. Sorry I missed that.

not a problem :)

chromeos cherrypick review: https://chromium-review.googlesource.com/c/502067/
Project Member

Comment 20 by bugdroid1@chromium.org, May 11 2017

The following revision refers to this bug:
  https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay/+/59092f0537dd09661fb82cf141efe1fb32fed2ef

commit 59092f0537dd09661fb82cf141efe1fb32fed2ef
Author: George Burgess IV <gbiv@google.com>
Date: Thu May 11 08:58:54 2017

llvm: cherrypick a fix for typeof(function)

Clang was picking the wrong type for typeof(foo) if foo was the only
function in an overload set that could have its address taken.
Specifically, it would pretend that the code said `typeof(&foo)`.

This fix should only be a functionality change for any code that uses
function pointers with overloaded functions, where the overloaded
functions use clang's pass_object_size or enable_if attributes. So, I
think the chance of this causing issues is low.

Cherrypicked commit message:

commit 432ed0e4a6d58f7dda8992a167aad43bc91f76c6
Author: George Burgess IV <george.burgess.iv@gmail.com>
Date:   Tue May 9 04:06:24 2017 +0000

    [Sema] Make typeof(OverloadedFunctionName) not a pointer.

    We were sometimes doing a function->pointer conversion in
    Sema::CheckPlaceholderExpr, which isn't the job of CheckPlaceholderExpr.

    So, when we saw typeof(OverloadedFunctionName), where
    OverloadedFunctionName referenced a name with only one function that
    could have its address taken, we'd give back a function pointer type
    instead of a function type. This is incorrect.

    I kept the logic for doing the function pointer conversion in
    resolveAndFixAddressOfOnlyViableOverloadCandidate because it was more
    consistent with existing ResolveAndFix* methods.

    git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@302506 91177308-0d34-0410-b5e6-96231b3b80d8

BUG= chromium:719020 
TEST=llvm and llvm-next cbuildbots on veyron_jaq, elm, falco pass;
local `emerge`s of clang and llvm (with and without USE=llvm-next)
succeed.

Change-Id: Ibcdba15557610bcc1e24c8d0fdd6790291ec1aac
Reviewed-on: https://chromium-review.googlesource.com/502067
Commit-Ready: George Burgess <gbiv@chromium.org>
Tested-by: George Burgess <gbiv@chromium.org>
Reviewed-by: Manoj Gupta <manojgupta@chromium.org>

[add] https://crrev.com/59092f0537dd09661fb82cf141efe1fb32fed2ef/sys-devel/llvm/files/cherry/432ed0e4a6d58f7dda8992a167aad43bc91f76c6.patch
[rename] https://crrev.com/59092f0537dd09661fb82cf141efe1fb32fed2ef/sys-devel/llvm/llvm-5.0_pre300080-r3.ebuild

Comment 21 by g...@chromium.org, May 11 2017

Status: Fixed (was: Assigned)
with a fresh `repo sync`:

(cr) gbiv@gbiv-desktop ~ $ cat foo.c
#include <stdlib.h>

typeof(realpath) *rp;

int main(void)
{
        return 0;
}
(cr) gbiv@gbiv-desktop ~ $ x86_64-cros-linux-gnu-clang -g -O2 foo.c
(cr) gbiv@gbiv-desktop ~ $ echo "whatis rp" | gdb -q a.out
Reading symbols from a.out...done.
(gdb) type = char *(*)(const char * restrict, char * restrict)

so, it looks to me like this is fixed. thanks again!
Labels: VerifyIn-61
Status: Verified (was: Fixed)
Closing. Please reopen it if its not fixed. Thanks!

Sign in to add a comment