Make -fstandalone-debug default on mingw
Yaron Keren
yaron.keren at gmail.com
Mon Sep 8 02:30:03 PDT 2014
Hi,
It does not seem a gcc bug, but rather a MinGW bug, a roblem with debug
info from libstdc++. With your example,
#include <fstream>
int main() {
std::ofstream f("foo.txt");
}
g++ a.cpp -g (or clang) on both Windows and Ubuntu produce a
DW_AT_declaration.
That's identical.
The difference is with libstdc++, on MinGW 4.82 (and 4.91) on Windows 7:
(gdb) info sharedlibrary
>From To Syms Read Shared Object Library
0x6fc41000 0x6fd32e00 Yes (*)
C:\Users\yaron\Downloads\mingw32\bin\libstdc++-6.dll
(*): Shared library is missing debugging information.
whereas with gcc 4.82 on Ubuntu 14:
(gdb) info sharedlibrary
>From To Syms Read Shared Object Library
0x00007ffff7b315c0 0x00007ffff7b9499a Yes
/usr/lib/x86_64-linux-gnu/libstdc++.so.6
indeed 'print f' on MingW fails with incomplete type whereas on Ubuntu it
pulls the debuginfo from libstdc++ and succeeds.
I don't think clang should workaround this but rather that minGW libstdc++
should be same as Linux with debug info. I'll report this to MingW-w64.
Yaron
2014-09-05 21:17 GMT+03:00 David Blaikie <dblaikie at gmail.com>:
>
>
>
> On Mon, Sep 1, 2014 at 2:28 PM, Yaron Keren <yaron.keren at gmail.com> wrote:
>
>> There is no debug variant of libstdc++, just release DLL, import lib for
>> this DLL and a static lib. You can see all the files (even without actually
>> running Windows) in the install 7z file:
>>
>>
>> http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/4.9.1/threads-posix/dwarf/
>>
>> Anyhow, for your example,
>>
>> mingw (gcc 4.9.1)
>> ------------------------
>>
>> 0x00000072: DW_TAG_structure_type [2] *
>> DW_AT_name [DW_FORM_string] ("foo")
>> DW_AT_declaration [DW_FORM_flag_present] (true)
>> DW_AT_sibling [DW_FORM_ref4] (cu + 0x008b =>
>> {0x0000008b})
>>
>> 0x0000007b: DW_TAG_subprogram [3] *
>> DW_AT_external [DW_FORM_flag_present] (true)
>> DW_AT_name [DW_FORM_string] ("foo")
>> DW_AT_artificial [DW_FORM_flag_present] (true)
>> DW_AT_declaration [DW_FORM_flag_present] (true)
>> DW_AT_object_pointer [DW_FORM_ref4] (cu + 0x0084 =>
>> {0x00000084})
>>
>> 0x00000084: DW_TAG_formal_parameter [4]
>> DW_AT_type [DW_FORM_ref4] (cu + 0x008b =>
>> {0x0000008b})
>> DW_AT_artificial [DW_FORM_flag_present] (true)
>>
>> 0x00000089: NULL
>>
>> 0x0000008a: NULL
>>
>>
>> clang trunk
>> --------------
>>
>> 0x00000037: DW_TAG_structure_type [3] *
>> DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000048] =
>> "foo")
>> DW_AT_declaration [DW_FORM_flag_present] (true)
>>
>> 0x0000003c: DW_TAG_subprogram [4] *
>> DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000048] =
>> "foo")
>> DW_AT_declaration [DW_FORM_flag_present] (true)
>> DW_AT_artificial [DW_FORM_flag_present] (true)
>> DW_AT_external [DW_FORM_flag_present] (true)
>> DW_AT_accessibility [DW_FORM_data1] (0x01)
>>
>> 0x00000042: DW_TAG_formal_parameter [5]
>> DW_AT_type [DW_FORM_ref4] (cu + 0x005b =>
>> {0x0000005b})
>> DW_AT_artificial [DW_FORM_flag_present] (true)
>>
>> 0x00000047: NULL
>>
>> 0x00000048: NULL
>>
>> clang -fstandalone-debug
>> ----------------------------------
>>
>> 0x00000037: DW_TAG_structure_type [3] *
>> DW_AT_containing_type [DW_FORM_ref4] (cu + 0x0037 =>
>> {0x00000037})
>> DW_AT_name [DW_FORM_strp] ( .debug_str[0x0000007a] =
>> "foo")
>> DW_AT_byte_size [DW_FORM_data1] (0x04)
>> DW_AT_decl_file [DW_FORM_data1] (0x01)
>> DW_AT_decl_line [DW_FORM_data1] (0x01)
>>
>> 0x00000043: DW_TAG_member [4]
>> DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000048] =
>> "_vptr$foo")
>> DW_AT_type [DW_FORM_ref4] (cu + 0x0075 => {0x00000075})
>> DW_AT_data_member_location [DW_FORM_data1] (0x00)
>> DW_AT_accessibility [DW_FORM_data1] (0x01)
>> DW_AT_artificial [DW_FORM_flag_present] (true)
>>
>> 0x0000004e: DW_TAG_subprogram [5] *
>> DW_AT_MIPS_linkage_name [DW_FORM_strp] (
>> .debug_str[0x00000066] = "_ZN3foo4funcEv")
>> DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000075] =
>> "func")
>> DW_AT_decl_file [DW_FORM_data1] (0x01)
>> DW_AT_decl_line [DW_FORM_data1] (0x01)
>> DW_AT_virtuality [DW_FORM_data1] (0x01)
>> DW_AT_vtable_elem_location [DW_FORM_exprloc] (<0x2> 10
>> 00 )
>> DW_AT_declaration [DW_FORM_flag_present] (true)
>> DW_AT_external [DW_FORM_flag_present] (true)
>> DW_AT_accessibility [DW_FORM_data1] (0x01)
>> DW_AT_containing_type [DW_FORM_ref4] (cu + 0x0037 =>
>> {0x00000037})
>>
>> 0x00000062: DW_TAG_formal_parameter [6]
>> DW_AT_type [DW_FORM_ref4] (cu + 0x008f =>
>> {0x0000008f})
>> DW_AT_artificial [DW_FORM_flag_present] (true)
>>
>> 0x00000067: NULL
>>
>> 0x00000068: DW_TAG_subprogram [7] *
>> DW_AT_name [DW_FORM_strp] ( .debug_str[0x0000007a] =
>> "foo")
>> DW_AT_declaration [DW_FORM_flag_present] (true)
>> DW_AT_artificial [DW_FORM_flag_present] (true)
>> DW_AT_external [DW_FORM_flag_present] (true)
>> DW_AT_accessibility [DW_FORM_data1] (0x01)
>>
>> 0x0000006e: DW_TAG_formal_parameter [6]
>> DW_AT_type [DW_FORM_ref4] (cu + 0x008f =>
>> {0x0000008f})
>> DW_AT_artificial [DW_FORM_flag_present] (true)
>>
>> 0x00000073: NULL
>>
>> 0x00000074: NULL
>>
>>
>> That's consistent.
>>
>> What's odd is for std::string gcc produces a definition while clang
>> produce a declaration only unless -fstandalone-debug. That what causes the
>> debug pretty printer problem.
>>
>
> Yep - that's because Clang has another similar, bit different,
> optimization that's founded on the same principle (the idea that you will
> compile your whole program/libraries with debug info), using explicit
> template instantiations as a hint that the debug info will be available
> elsewhere anyway. GCC doesn't implement that particular optimization, but
> my point in the above example is that it implements similar things that are
> just as problematic for a user without debug libraries.
>
> A specific STL example would be:
>
> #include <fstream>
>
> int main() {
> std::ofstream f("foo.txt");
> }
>
> Both Clang and GCC produce:
>
> DW_TAG_class_type [5]
> DW_AT_name [DW_FORM_strp] ( .debug_str[0x000000c7] =
> "basic_ofstream<char, std::char_traits<char> >")
> DW_AT_declaration [DW_FORM_flag_present] (true)
>
> Because the vtable for basic_ofstream<char> is compiled into libstdc++.
>
>
>> #include <string>
>> int main() {
>> std::string s("hello");
>> }
>>
>> Since both gcc and clang share the same header files, library files and
>> linker, it would seem that the decision rule when to produce a debug class
>> definition is different between gcc and clang at least for std::string.
>>
>
> Yep - the explicit template instantiation being the trigger clang is using
> for that. My vtable example was to demonstrate that GCC uses similar
> reasoning for other things (where GCC and Clang overlap more closely).
>
> That said, I know next to nothing about MinGW distribution and "GCC does
> this" isn't itself an argument for Clang to do something, so I'm not
> exactly going to block this patch.
>
> Do you have any idea if someone's filed a similar bug on GCC (do you care
> about GCC behavior, or only Clang?)? Any idea what their response was? (I
> imagine people in the GCC community might have more familiarity with
> MinGW/libstdc++ distribution practices than I do, and might have some other
> ideas about whether it's the right direction)
>
>
>>
>> Yaron
>>
>>
>>
>>
>> 2014-09-01 22:25 GMT+03:00 David Blaikie <dblaikie at gmail.com>:
>>
>>
>>>
>>>
>>> On Mon, Sep 1, 2014 at 11:38 AM, Yaron Keren <yaron.keren at gmail.com>
>>> wrote:
>>>
>>>> http://llvm.org/bugs/show_bug.cgi?id=20741
>>>>
>>>> With the current default, a programmer compiling his program with clang
>>>> -g will not get debug info for std::string members and thus the gdb pretty
>>>> printer for std::string will fail. That's how I noticed the problem in the
>>>> first place. Given that libstdc++ is used in every C++ program and that
>>>> std::string is quite popular, this isn't a good result.
>>>>
>>>
>>> On most linux distributions, there's a -dbg variant of libstdc++ that
>>> users can install to get the library's debug information (GCC relies on
>>> this for various parts of its debug output, for example - I'd be curious to
>>> know if their default is any different on MinGW). Is there no such thing on
>>> MinGW? (do you know if GCC does the same thing? try compiling this source
>>> file to an object file with gcc: "struct foo { virtual void func(); } foo
>>> f;" and see if GCC emits the definition of 'foo', or just a declaration -
>>> on Linux it'll only produce a declaration)
>>>
>>>
>>>>
>>>> This patch makes -fstandalone-debug default on mingw.
>>>>
>>>>
>>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140908/d9d5e228/attachment.html>
More information about the cfe-commits
mailing list