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

#include <ostream> vs #include "ostream" #60

Closed
vsapsai opened this issue Jun 15, 2015 · 19 comments
Closed

#include <ostream> vs #include "ostream" #60

vsapsai opened this issue Jun 15, 2015 · 19 comments

Comments

@vsapsai
Copy link
Contributor

vsapsai commented Jun 15, 2015

Originally reported on Google Code with ID 60

What steps will reproduce the problem?  Give the *exact* arguments passed
to include-what-you-use, and attach the input source file that gives the
problem (minimal test-cases are much appreciated!)
1. Use iwyu on a file missing some system includes
2. Compiling using cmake (cf #26), but issue is not related

What is the expected output? What do you see instead?

This is what I get:

#include <stdlib.h>                     // for atoi, atof, EXIT_SUCCESS
#include <string>                       // for operator==
#include "new"                          // for operator delete[], etc
#include "ostream"                      // for operator<<

I'd like to get:

#include <stdlib.h>                     // for atoi, atof, EXIT_SUCCESS
#include <string>                       // for operator==
#include <new>                          // for operator delete[], etc
#include <ostream>                      // for operator<<

What version of the product are you using? On what operating system?

iwyu revision: 304
gcc 4.6.1 on a Linux Debian testing.

Please provide any additional information below.

I suspect it's related to some missing case in iwyu_include_picker.cc
I will come with a minimal test case if necessary.

Reported by emmanuel.christophe on 2011-09-23 05:49:35

@vsapsai
Copy link
Contributor Author

vsapsai commented Jun 15, 2015

My guess is it is an issue with cmake actually, though it's hard to tell with the data
given.  It's unlikely to be iwyu_include_picker.cc.

Assuming ostream is a newly added include, iwyu decides whether to use <> or "" based
on whether the file is in a 'system' directory.  It gets the list of system directories
from clang.  If you provide the full output of the iwyu run, it should say where ostream
lives.  Then you'll need to figure out what arguments cmake provides to iwyu (if any)
to see what the system directories are.  Otherwise it will be the default system directories,
which you can easily find by running iwyu in the debugger, though it may be possible
some other way, via clang tools.

If you can't figure it out, the most useful info for you to include would be the *full*
output of the iwyu run, and the exact command you used to run iwyu.  A minimal test
case, as you suspect, would also be helpful, but not as helpful as the first two.

Reported by csilvers on 2011-09-23 14:43:20

@vsapsai
Copy link
Contributor Author

vsapsai commented Jun 15, 2015

Attached is the full command (output-command) and the verbose output of iwuy (output-verbose).
Let me know if there is a way to get more information out.

Reported by emmanuel.christophe on 2011-09-24 18:37:42


- _Attachment: [output-command](https://storage.googleapis.com/google-code-attachments/include-what-you-use/issue-60/comment-2/output-command)_ - _Attachment: [output-verbose](https://storage.googleapis.com/google-code-attachments/include-what-you-use/issue-60/comment-2/output-verbose)_

@vsapsai
Copy link
Contributor Author

vsapsai commented Jun 15, 2015

Thanks!  The -v flag you gave was passed to clang, not iwyu.  For iwyu-verbose output,
you need to do
   -Xiwyu --v=6

--v=6 will be a *lot* of output.  It will also share a lot about the content of your
file.  --v=3 is likely enough, if either of those two facts concerns you.

Reported by csilvers on 2011-09-26 18:28:42

@vsapsai
Copy link
Contributor Author

vsapsai commented Jun 15, 2015

No issue with sharing the content of the file (this is on an open source project). The
v=3 does not gave me much: it's following some typedef, but I still don't get the 
operator new[] is defined in "new"

v=6 ended up on a segfault, not sure if it went all the way. I couldn't find the lines
that appear on the v=3. Do you confirm that all v=3 output should appear on the v=6?
(if it is, I can explore the segfault further).

Reported by emmanuel.christophe on 2011-09-27 05:38:35


- _Attachment: [output-verbose3](https://storage.googleapis.com/google-code-attachments/include-what-you-use/issue-60/comment-4/output-verbose3)_ - _Attachment: [output-verbose6.bz2](https://storage.googleapis.com/google-code-attachments/include-what-you-use/issue-60/comment-4/output-verbose6.bz2)_

@vsapsai
Copy link
Contributor Author

vsapsai commented Jun 15, 2015

OK, --v=6 was enough to get the info I needed (even before the crash, which definitely
shouldn't be happening, but may be a bug in clang that I wouldn't know how to fix).

Here's what iwyu says:
   Search path: /usr/include/c++/4.6 (user)

The question is, why?  I see this
   Search path: /usr/include/c++/4.6/x86_64-linux-gnu/ (system)
   Search path: /usr/include/c++/4.6/backward (system)
so it's getting the subdirs right.  And I also see
   Search path: /usr/include/c++/4.5 (system)
   Search path: /usr/include/c++/4.4 (system)
so it's just 4.6 that's affected.

Your previous verbose output (which proved useful in itself!) says this:

#include "..." search starts here:
#include <...> search starts here:
  [...]
 /usr/include/c++/4.6

So whatever is producing that (clang somewhere?) thinks this is a system directory.
I don't know why we don't.

If you're up for debugging clang, the relevant function is ComputeHeaderSearchPaths
in iwyu_globals.cc.  It would be useful to see if /usr/include/c++/4.6 is showing up
in the system_dir_begin()/system_dir_end().  It would also be useful, after this function
exits, to print the result vector and see what it contains.  In particular, I notice
this:
     const char* path_type_name
        = (it->path_type == HeaderSearchPath::kSystemPath ? "system" : "user");
I wonder if it->path_type is garbage for /usr/include/c++/4.6, due to memory corruption
or some such.

Reported by csilvers on 2011-09-27 17:52:22

@vsapsai
Copy link
Contributor Author

vsapsai commented Jun 15, 2015

At the end of ComputeHeaderSearchPaths, in search_path_map I have:

[...]
/home/christop/OTB/trunk/OTB/Utilities/otbsiftfast -> 2
/home/christop/OTB/trunk/OTB/Utilities/otbsvm -> 2
/home/christop/OTB/trunk/OTB/Utilities/tinyXMLlib -> 2
/home/christop/opensource/llvm-bin-debug/bin/../lib/clang/3.0/include -> 1
/usr/include -> 1
/usr/include/c++/4.4 -> 1
/usr/include/c++/4.4/backward -> 1
/usr/include/c++/4.4/x86_64-linux-gnu/ -> 1
/usr/include/c++/4.5 -> 1
/usr/include/c++/4.5/backward -> 1
/usr/include/c++/4.5/x86_64-linux-gnu/ -> 1
/usr/include/c++/4.6 -> 2
/usr/include/c++/4.6/backward -> 1
/usr/include/c++/4.6/x86_64-linux-gnu/ -> 1
/usr/include/x86_64-linux-gnu -> 1
/usr/local/include -> 1

So it is not garbage for /usr/include/c++/4.6, but it is the wrong type (user). So
it doesn't seem to be memory corruption.

I also attached the backtrace of the segfault as it may be related.

I'll try to update llvm/clang/iwuy and see if it's still happening.

Reported by emmanuel.christophe on 2011-10-02 17:11:52


- _Attachment: [output-bt](https://storage.googleapis.com/google-code-attachments/include-what-you-use/issue-60/comment-6/output-bt)_

@vsapsai
Copy link
Contributor Author

vsapsai commented Jun 15, 2015

Hmm, I think you'll have to run this through the debugger, then, to see what is going
on in the routines that create this map.  We're just copying data from clang, so it's
likely the issue is there somewhere, and not in iwyu.  But it's difficult to be sure.

Reported by csilvers on 2011-10-03 15:57:08

@vsapsai
Copy link
Contributor Author

vsapsai commented Jun 15, 2015

I've tried to reproduce this issue on Mac OS X 10.6.8, but unsuccessfully. I've received
OTB/Testing/Code/BasicFilters/otbFrostFilterNew.cxx should add these lines:
#include <stdlib.h>                     // for EXIT_SUCCESS
#include <iostream>                     // for operator<<, ostream, cout, endl
<skipped>

Though I haven't configured OTB properly and encountered en error
OTB/Utilities/ITK/Code/Common/itkWin32Header.h:23:10: fatal error: 'itkConfigure.h'
file not found

But I have prepared a small test case to reproduce segfault (please find attached).
Seems like it is a problem in clang, but I don't know what is the best way to report
AST-related bugs, especially how to reproduce them. iwyu r323, llvm/clang r141492

Reported by vsapsai on 2011-10-08 16:13:48


- _Attachment: [reproduce_crash.zip](https://storage.googleapis.com/google-code-attachments/include-what-you-use/issue-60/comment-8/reproduce_crash.zip)_ - _Attachment: [main.cc](https://storage.googleapis.com/google-code-attachments/include-what-you-use/issue-60/comment-8/main.cc)_ - _Attachment: [itk_fixed_array.h](https://storage.googleapis.com/google-code-attachments/include-what-you-use/issue-60/comment-8/itk_fixed_array.h)_ - _Attachment: [itk_image_base.h](https://storage.googleapis.com/google-code-attachments/include-what-you-use/issue-60/comment-8/itk_image_base.h)_ - _Attachment: [itk_vector.h](https://storage.googleapis.com/google-code-attachments/include-what-you-use/issue-60/comment-8/itk_vector.h)_

@vsapsai
Copy link
Contributor Author

vsapsai commented Jun 15, 2015

I went through the debugger and the creation of the header path seems to be correct
on the clang side. More precisely, at the end of InitHeaderSearch::Realize (in InitHeaderSearch.cpp),
I do have /usr/include/c++/4.6 with the SrcMgr::C_System type.

Something is interpreting it as a user directory later on, but I don't know what. Two
troubling facts:
- in the header list, "/usr/include/c++/4.6" is the first system directory after a
bunch of user directories.
- the RemoveDuplicates happens to remove one user directory
so in the header list, "/usr/include/c++/4.6" ends up at a position that was previously
occupied by a user directory, if something externally 'remembers' a number of user
directory without being updated, that would explain it.

Reported by emmanuel.christophe on 2011-10-09 07:29:21

@vsapsai
Copy link
Contributor Author

vsapsai commented Jun 15, 2015

I confirm that there is an issue with the system_dir_begin() iterator: in ComputeHeaderSearchPaths
in iwuy_globals.cc I have:

(gdb) p (*header_search).SearchDirs[75]
$78 = (clang::DirectoryLookup &) @0x1acbed0: {u = {Dir = 0x1abb6d0, Map = 0x1abb6d0},

  DirCharacteristic = 0, UserSupplied = true, LookupType = 0, IsIndexHeaderMap = 0}
(gdb) p (*header_search).SearchDirs[76]
$79 = (clang::DirectoryLookup &) @0x1acbee0: {u = {Dir = 0x1abb710, Map = 0x1abb710},

  DirCharacteristic = 1, UserSupplied = false, LookupType = 0, IsIndexHeaderMap = 0}
(gdb) p (*header_search).SearchDirs[77]
$80 = (clang::DirectoryLookup &) @0x1acbef0: {u = {Dir = 0x1abb750, Map = 0x1abb750},

  DirCharacteristic = 1, UserSupplied = false, LookupType = 0, IsIndexHeaderMap = 0}
(gdb) p header_search->system_dir_begin()
$81 = {_M_current = 0x1acbef0}

[76] is "/usr/include/c++/4.6" with DirCharacteristic = 1 and UserSupplied = false
it's clearly a system header, but the system_dir_begin() is pointing to the next one.
The SystemDirIdx in clang HeaderSearch is probably missing an update during the RemoveDuplicates.

Would it be possible to get iwuy to rely on the DirCharacteristic instead of the system_dir_begin?

I can submit a patch if you are ok with this change.

Reported by emmanuel.christophe on 2011-10-09 23:20:59

@vsapsai
Copy link
Contributor Author

vsapsai commented Jun 15, 2015

For reference:
I filed a bug for clang http://llvm.org/bugs/show_bug.cgi?id=11097

Reported by emmanuel.christophe on 2011-10-10 03:04:12

@vsapsai
Copy link
Contributor Author

vsapsai commented Jun 15, 2015

Nice! -- I agree that the best way to resolve this is to fix the bug in clang.  I would
rather do that than do a workaround in iwyu.

It may be possible for you to fix it yourself and supply a patch (and a testcase?)
-- I know the clang folks are responsive to that, though I don't know how easy it is
to fix.  It's unlikely to get fixed soon otherwise, I'm guessing.

In the meantime, is it possible for you to run iwyu without the duplicate include-path
entries?  That would avoid triggering this bug, if I understand what's going on correctly.

Reported by csilvers on 2011-10-10 06:25:13

@vsapsai
Copy link
Contributor Author

vsapsai commented Jun 15, 2015

That's pretty easy to fix in clang, I've just posted a patch. I'll update with the revision
number here once this is fixed in clang.

Reported by emmanuel.christophe on 2011-10-10 07:22:29

@vsapsai
Copy link
Contributor Author

vsapsai commented Jun 15, 2015

Great, thanks much!

Reported by csilvers on 2011-10-10 18:40:24

@vsapsai
Copy link
Contributor Author

vsapsai commented Jun 15, 2015

Committed clang revision 141565.

Reported by Chad.Rosier on 2011-10-10 18:49:53

@vsapsai
Copy link
Contributor Author

vsapsai commented Jun 15, 2015

So my understanding is that fixing the bug in clang should cause the problem you've
seen to go away.  Can you verify that it has?  If so, I'll close the bug.

Reported by csilvers on 2011-10-10 21:03:18

@vsapsai
Copy link
Contributor Author

vsapsai commented Jun 15, 2015

Yes, we can close the bug, the segfault with --v=6 is likely to be clang related as
well.

Reported by emmanuel.christophe on 2011-10-11 05:15:36

@vsapsai
Copy link
Contributor Author

vsapsai commented Jun 15, 2015

Reported by csilvers on 2011-10-11 18:27:40

  • Status changed: Verified

@vsapsai
Copy link
Contributor Author

vsapsai commented Jun 15, 2015

Reported by csilvers on 2011-10-11 18:27:54

  • Status changed: Fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant