<div dir="rtl"><div dir="ltr">Hi,</div><div dir="ltr"><br></div><div dir="ltr">It does not seem a gcc bug, but rather a MinGW bug, a roblem with debug info from libstdc++. With your example, </div><div dir="ltr"><br></div><div dir="ltr"><div>#include <fstream></div><div>int main() {</div><div>  std::ofstream f("foo.txt");</div><div>}<br></div></div><div dir="ltr"><br></div><div dir="ltr">g++ a.cpp -g  (or clang) on both Windows and Ubuntu produce a <span style="font-family:arial,sans-serif;font-size:12.7272720336914px">DW_AT_declaration. That's identical.</span></div><div dir="ltr"><br></div><div dir="ltr"><div style="font-family:arial,sans-serif;font-size:12.7272720336914px"><span style="font-size:12.7272720336914px">The difference is with libstdc++, on </span><span style="font-size:small;font-family:arial">MinGW 4.82 (and 4.91) on Windows 7:</span><br></div><div style="font-family:arial,sans-serif;font-size:12.7272720336914px"><span style="font-family:arial;font-size:small"><br></span></div><div style><div style="font-family:arial,sans-serif;font-size:12.7272720336914px">(gdb) info sharedlibrary</div><div style="font-family:arial,sans-serif;font-size:12.7272720336914px">From        To          Syms Read   Shared Object Library</div><div style="font-family:arial,sans-serif;font-size:12.7272720336914px"><span style="font-size:12.7272720336914px">0x6fc41000  0x6fd32e00  Yes (*)     C:\Users\yaron\Downloads\mingw32\bin\libstdc++-6.dll</span><br></div><div style><font face="arial, sans-serif">(*): Shared library is missing debugging information.</font><br></div></div><div style="font-family:arial,sans-serif;font-size:12.7272720336914px"><span style="font-family:arial;font-size:small"><br></span></div><div style="font-family:arial,sans-serif;font-size:12.7272720336914px"><span style="font-family:arial;font-size:small">whereas with</span><span style="font-size:small;font-family:arial"> </span><span style="font-size:12.7272720336914px">gcc 4.82 on </span><span style="font-size:small;font-family:arial">Ubuntu 14:</span></div><div style="font-family:arial,sans-serif;font-size:12.7272720336914px"><br></div></div><div dir="ltr"><div dir="ltr">(gdb) info sharedlibrary </div><div dir="ltr">From                To                  Syms Read   Shared Object Library</div><div dir="ltr">0x00007ffff7b315c0  0x00007ffff7b9499a  Yes         /usr/lib/x86_64-linux-gnu/libstdc++.so.6<br></div><div><br></div><div>indeed 'print f' on MingW fails with incomplete type whereas on Ubuntu it pulls the debuginfo from libstdc++ and succeeds.</div><div><br></div><div>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.</div><div><br></div><div>Yaron</div><div><br></div></div><div dir="ltr"><br></div><div dir="ltr"><br></div><div class="gmail_extra" dir="ltr"><div><br><div class="gmail_quote">2014-09-05 21:17 GMT+03:00 David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><br><div class="gmail_extra"><br><br><div class="gmail_quote"><div><div class="h5">On Mon, Sep 1, 2014 at 2:28 PM, Yaron Keren <span dir="ltr"><<a href="mailto:yaron.keren@gmail.com" target="_blank">yaron.keren@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div><div>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:</div>


<div><br></div><div> <a href="http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/4.9.1/threads-posix/dwarf/" target="_blank">http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/4.9.1/threads-posix/dwarf/</a><br>


</div><div><br></div><div>Anyhow, for your example,</div><div><br></div><div>mingw (gcc 4.9.1)</div><div>------------------------</div><div><br></div><div>


<div>0x00000072:   DW_TAG_structure_type [2] *</div><div>                DW_AT_name [DW_FORM_string]<span style="white-space:pre-wrap">       </span>("foo")</div><div>                DW_AT_declaration [DW_FORM_flag_present]<span style="white-space:pre-wrap">        </span>(true)</div>


<div>                DW_AT_sibling [DW_FORM_ref4]<span style="white-space:pre-wrap">      </span>(cu + 0x008b => {0x0000008b})</div><div><br></div><div>0x0000007b:     DW_TAG_subprogram [3] *</div>


<div>                  DW_AT_external [DW_FORM_flag_present]<span style="white-space:pre-wrap">   </span>(true)</div><div>                  DW_AT_name [DW_FORM_string]<span style="white-space:pre-wrap">      </span>("foo")</div>


<div>                  DW_AT_artificial [DW_FORM_flag_present]<span style="white-space:pre-wrap"> </span>(true)</div><div>                  DW_AT_declaration [DW_FORM_flag_present]<span style="white-space:pre-wrap"> </span>(true)</div>


<div>                  DW_AT_object_pointer [DW_FORM_ref4]<span style="white-space:pre-wrap">     </span>(cu + 0x0084 => {0x00000084})</div><div><br></div><div>0x00000084:       DW_TAG_formal_parameter [4]  </div>


<div>                    DW_AT_type [DW_FORM_ref4]<span style="white-space:pre-wrap">     </span>(cu + 0x008b => {0x0000008b})</div><div>                    DW_AT_artificial [DW_FORM_flag_present]<span style="white-space:pre-wrap">      </span>(true)</div>


<div><br></div><div>0x00000089:       NULL</div><div><br></div><div>0x0000008a:     NULL</div><div><br></div></div><div><br></div><div>clang trunk<br></div><div>


--------------</div><div><br></div><div><div>0x00000037:   DW_TAG_structure_type [3] *</div><div>                DW_AT_name [DW_FORM_strp]<span style="white-space:pre-wrap">   </span>( .debug_str[0x00000048] = "foo")</div>


<div>                DW_AT_declaration [DW_FORM_flag_present]<span style="white-space:pre-wrap">  </span>(true)</div><div><br></div><div>0x0000003c:     DW_TAG_subprogram [4] *</div><div>


                  DW_AT_name [DW_FORM_strp]<span style="white-space:pre-wrap">  </span>( .debug_str[0x00000048] = "foo")</div><div>                  DW_AT_declaration [DW_FORM_flag_present]<span style="white-space:pre-wrap">    </span>(true)</div>


<div>                  DW_AT_artificial [DW_FORM_flag_present]<span style="white-space:pre-wrap"> </span>(true)</div><div>                  DW_AT_external [DW_FORM_flag_present]<span style="white-space:pre-wrap">    </span>(true)</div>


<div>                  DW_AT_accessibility [DW_FORM_data1]<span style="white-space:pre-wrap">     </span>(0x01)</div><div><br></div><div>0x00000042:       DW_TAG_formal_parameter [5]  </div>
<div>
                    DW_AT_type [DW_FORM_ref4]<span style="white-space:pre-wrap">        </span>(cu + 0x005b => {0x0000005b})</div><div>                    DW_AT_artificial [DW_FORM_flag_present]<span style="white-space:pre-wrap">      </span>(true)</div>


<div><br></div><div>0x00000047:       NULL</div><div><br></div><div>0x00000048:     NULL</div><div><br></div><div>clang -fstandalone-debug</div><div>----------------------------------</div>


<div><br></div><div><div>0x00000037:   DW_TAG_structure_type [3] *</div><div>                DW_AT_containing_type [DW_FORM_ref4]<span style="white-space:pre-wrap">  </span>(cu + 0x0037 => {0x00000037})</div><div>                DW_AT_name [DW_FORM_strp]<span style="white-space:pre-wrap">        </span>( .debug_str[0x0000007a] = "foo")</div>


<div>                DW_AT_byte_size [DW_FORM_data1]<span style="white-space:pre-wrap">   </span>(0x04)</div><div>                DW_AT_decl_file [DW_FORM_data1]<span style="white-space:pre-wrap">    </span>(0x01)</div>

<div>                DW_AT_decl_line [DW_FORM_data1]<span style="white-space:pre-wrap">   </span>(0x01)</div><div><br></div><div>0x00000043:     DW_TAG_member [4]  </div><div>                  DW_AT_name [DW_FORM_strp]<span style="white-space:pre-wrap">     </span>( .debug_str[0x00000048] = "_vptr$foo")</div>


<div>                  DW_AT_type [DW_FORM_ref4]<span style="white-space:pre-wrap">       </span>(cu + 0x0075 => {0x00000075})</div><div>                  DW_AT_data_member_location [DW_FORM_data1]<span style="white-space:pre-wrap">     </span>(0x00)</div>


<div>                  DW_AT_accessibility [DW_FORM_data1]<span style="white-space:pre-wrap">     </span>(0x01)</div><div>                  DW_AT_artificial [DW_FORM_flag_present]<span style="white-space:pre-wrap">  </span>(true)</div>


<div><br></div><div>0x0000004e:     DW_TAG_subprogram [5] *</div><div>                  DW_AT_MIPS_linkage_name [DW_FORM_strp]<span style="white-space:pre-wrap">   </span>( .debug_str[0x00000066] = "_ZN3foo4funcEv")</div>


<div>                  DW_AT_name [DW_FORM_strp]<span style="white-space:pre-wrap">       </span>( .debug_str[0x00000075] = "func")</div><div>                  DW_AT_decl_file [DW_FORM_data1]<span style="white-space:pre-wrap">    </span>(0x01)</div>


<div>                  DW_AT_decl_line [DW_FORM_data1]<span style="white-space:pre-wrap"> </span>(0x01)</div><div>                  DW_AT_virtuality [DW_FORM_data1]<span style="white-space:pre-wrap"> </span>(0x01)</div>

<div>                  DW_AT_vtable_elem_location [DW_FORM_exprloc]<span style="white-space:pre-wrap">    </span>(<0x2> 10 00 )</div><div>                  DW_AT_declaration [DW_FORM_flag_present]<span style="white-space:pre-wrap">   </span>(true)</div>


<div>                  DW_AT_external [DW_FORM_flag_present]<span style="white-space:pre-wrap">   </span>(true)</div><div>                  DW_AT_accessibility [DW_FORM_data1]<span style="white-space:pre-wrap">      </span>(0x01)</div>


<div>                  DW_AT_containing_type [DW_FORM_ref4]<span style="white-space:pre-wrap">    </span>(cu + 0x0037 => {0x00000037})</div><div><br></div><div>0x00000062:       DW_TAG_formal_parameter [6]  </div><div>

                    DW_AT_type [DW_FORM_ref4]<span style="white-space:pre-wrap">        </span>(cu + 0x008f => {0x0000008f})</div><div>                    DW_AT_artificial [DW_FORM_flag_present]<span style="white-space:pre-wrap">      </span>(true)</div>


<div><br></div><div>0x00000067:       NULL</div><div><br></div><div>0x00000068:     DW_TAG_subprogram [7] *</div><div>                  DW_AT_name [DW_FORM_strp]<span style="white-space:pre-wrap">  </span>( .debug_str[0x0000007a] = "foo")</div>


<div>                  DW_AT_declaration [DW_FORM_flag_present]<span style="white-space:pre-wrap">        </span>(true)</div><div>                  DW_AT_artificial [DW_FORM_flag_present]<span style="white-space:pre-wrap">  </span>(true)</div>


<div>                  DW_AT_external [DW_FORM_flag_present]<span style="white-space:pre-wrap">   </span>(true)</div><div>                  DW_AT_accessibility [DW_FORM_data1]<span style="white-space:pre-wrap">      </span>(0x01)</div>


<div><br></div><div>0x0000006e:       DW_TAG_formal_parameter [6]  </div><div>                    DW_AT_type [DW_FORM_ref4]<span style="white-space:pre-wrap">      </span>(cu + 0x008f => {0x0000008f})</div><div>                    DW_AT_artificial [DW_FORM_flag_present]<span style="white-space:pre-wrap">      </span>(true)</div>


<div><br></div><div>0x00000073:       NULL</div><div><br></div><div>0x00000074:     NULL</div></div><div><br></div><div><br></div><div>That's consistent.</div><div><br></div><div>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.</div>
</div></div></blockquote><div><br></div></div></div><div>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.<br>
<br>A specific STL example would be:<br><br>  #include <fstream><div><br></div><div>  int main() {</div><div>    std::ofstream f("foo.txt");</div><div>  }</div><br>Both Clang and GCC produce:<br><div><br></div>
<div>  DW_TAG_class_type [5]  </div><div>    DW_AT_name [DW_FORM_strp]     ( .debug_str[0x000000c7] = "basic_ofstream<char, std::char_traits<char> >")</div><div>    DW_AT_declaration [DW_FORM_flag_present]      (true)</div>
</div><div> <br>Because the vtable for basic_ofstream<char> is compiled into libstdc++.<br><br></div><span class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div dir="rtl"><div dir="ltr">

<div><br></div><div><div>#include <string></div><div>int main() {</div><div>  std::string s("hello");</div><div>}<br></div></div><div><br></div><div>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.</div>
</div></div></blockquote><div><br></div></span><div>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).<br>
<br>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.<br><br>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)</div><span class=""><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="rtl"><div dir="ltr">


<div><br></div><div>Yaron</div><div><br></div></div><div dir="ltr"><br></div></div><div class="gmail_extra"><div dir="ltr"><br><br><div class="gmail_quote">2014-09-01 22:25 GMT+03:00 David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>></span>:<div>
<div><br>

<blockquote class="gmail_quote" style="margin:0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;border-right-width:1px;border-right-color:rgb(204,204,204);border-right-style:solid;padding-left:1ex;padding-right:1ex">
<br><div class="gmail_extra"><br><br><div class="gmail_quote"><div>
On Mon, Sep 1, 2014 at 11:38 AM, Yaron Keren <span dir="ltr"><<a href="mailto:yaron.keren@gmail.com" target="_blank">yaron.keren@gmail.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="rtl"><div dir="ltr"><a href="http://llvm.org/bugs/show_bug.cgi?id=20741" target="_blank">http://llvm.org/bugs/show_bug.cgi?id=20741</a><br>



<br>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.</div>



</div></blockquote><div><br></div></div><div>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)</div>


<div>
<div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="rtl">

<div dir="ltr"><br></div><div dir="ltr">This patch makes  -fstandalone-debug default on mingw.</div><div dir="ltr"><br></div></div>
</blockquote></div></div><br></div></blockquote></div></div></div></div></div>
</blockquote></span></div><br></div></blockquote></div></div></div></div>