DWARF 5 proposes a reinvented .debug_macro section. This change follows
that spec.
Currently, only GCC produces the .debug_macro section and hence
the added test is annottated with expectedFailureClang.
Paths
| Differential D15437
Read macro info from .debug_macro section and use it for expression evaluation. ClosedPublic Authored by sivachandra on Dec 10 2015, 6:18 PM.
Details
Summary DWARF 5 proposes a reinvented .debug_macro section. This change follows Currently, only GCC produces the .debug_macro section and hence
Diff Detail Event Timelinesivachandra retitled this revision from to Read macro info from .debug_macro section and use it for expression evaluation.. sivachandra updated this object. Comment Actions The dwo_test_method fails for the added test as I think there is some GCC bug with the combination of -gsplit-dwarf and -g3. Comment Actions I should also mention that I did not implement the complete spec as I do not know of any producer which produces all the flavors of the new spec. Comment Actions The high level architecture looks reasonable but there are a few think I would like you to clean up a bit:
How much advantage do you expect from this change from the users point of view? Do you think we should try to make clang produce .debug_macros section also? In case of split dwarf gcc produces several .debug_macro.dwo section for each compile unit what won't work with your current implementation. I haven't checked the spec if gcc-s behavior is correct or not but it might be a good idea to support it (not necessary with this change). If you decide to not support split dwarf then please mark the test as XFAIL(dwo) also
clayborg edited edge metadata. Comment ActionsMy main concern here is efficient storage. See my inline comment regarding DebugMacroEntryStorage and let me know what you think.
This revision now requires changes to proceed.Dec 11 2015, 10:40 AM sivachandra edited edge metadata. sivachandra marked 11 inline comments as done. Comment ActionsAddress comments. Comment Actions I have addressed all the comments (with changes or my own comments). About the problem with dwo, I have sent a mail to the GCC guys asking for guidance. Will fix it when I get clarity on that. And yes, it would definitely be good if clang can also produce .debug_macro sections.
clayborg edited edge metadata. Comment ActionsCan we change DebugMacroEntry to contain a std::unique_ptr<DebugMacro> instead of a shared pointer? This would save us one full pointer in each DebugMacroEntry. That is the only change I would like to see. The expand on the benefit of having two structs like DebugMacroEntryStorage would be you can store it very efficiently with bitfields and store the macros inside DebugMacro as a vector of DebugMacroEntryStorage structs. But the API from DebugMacro could that gets an entry at index could return the bigger fatter version of this. The two structs below would be an example: We store macro entries inside DebugMacro as: class DebugMacroEntryStorage { EntryType m_type:3; uint32_t m_line:29; uint32_t m_file; ConstString m_str; DebugMacrosSP m_debug_macros_sp; }; But the function: DebugMacroEntry GetMacroEntryAtIndex(const size_t index) const would return something like: class DebugMacroEntryStorage { CompileUnit *m_comp_unit; EntryType m_type; uint32_t m_line; FileSpec m_file; ConstString m_str; DebugMacrosSP m_debug_macros_sp; }; We would resolve the "m_file" into a FileSpec for public consumption by getting the correct file from the compile unit's support files FileSpecList and not compress the storage and also fill in the m_comp_unit if needed. This doesn't need to be done, but this is what I was thinking. I did this in LineTable.h where I store line entries as a lldb_private::LineTable::Entry objects, but I hand them out to clients as lldb_private::LineEntry objects. This revision now requires changes to proceed.Dec 11 2015, 3:27 PM clayborg edited edge metadata. Comment Actions
Actually never mind. I believe the whole reason this shared pointer is here it to share the object between multiple other objects... This revision is now accepted and ready to land.Dec 11 2015, 3:29 PM Comment Actions One area of concern is if you are not tracking file, how can you get the right defines for a given source file line? If you have: main.c: #include <foo.h> #define FOO printf int main () { return 0; // Stop here and run: FOO("hello world\n") } #undef FOO But in foo.h you have: nothing #undef FOO Do you currently correctly have the following in your macros if stopped at the return statement in main? #define FOO puts <<< from foo.h Both foo definitions will be on line 1, and we will be stopped on line 5 of main.c, but if we don't know that the entries from foo.h come from foo.h we might accidentally include these statements? Comment Actions The spec says that, for a given compile unit, the macro entries in the debug info will be in the order in which the compiler processes them. Hence, at line 5 in your example, all these are relevant: #define FOO puts <<< from foo.h #undef FOO <<< from foo.h #define FOO print <<< from main.c I have actually verified that it works as expected; FOO resolves to printf and not puts at line 5. You have tickled one aspect that I have ignored though. What if one is stopped in an inlined function/method defined in an included file? I think taking care of this is a fairly straightforward change over what I now have. I will need to bring back the line index in DebugMacroEntry and use it. Will send an update soon.
sivachandra marked 2 inline comments as done. Comment ActionsRemove storing of an unused data structure. Closed by commit rL255729: Read macro info from .debug_macro section and use it for expression evaluation. (authored by sivachandra). · Explain WhyDec 15 2015, 4:25 PM This revision was automatically updated to reflect the committed changes.
Revision Contents
Diff 42758 include/lldb/Symbol/CompileUnit.h
include/lldb/Symbol/DebugMacros.h
include/lldb/Symbol/SymbolFile.h
include/lldb/Symbol/SymbolVendor.h
include/lldb/lldb-enumerations.h
packages/Python/lldbsuite/test/expression_command/macros/Makefile
packages/Python/lldbsuite/test/expression_command/macros/TestMacros.py
packages/Python/lldbsuite/test/expression_command/macros/macro1.h
packages/Python/lldbsuite/test/expression_command/macros/macro2.h
packages/Python/lldbsuite/test/expression_command/macros/main.cpp
packages/Python/lldbsuite/test/make/Makefile.rules
source/Expression/ExpressionSourceCode.cpp
source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
source/Plugins/SymbolFile/DWARF/CMakeLists.txt
source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h
source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp
source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
source/Symbol/CMakeLists.txt
source/Symbol/CompileUnit.cpp
source/Symbol/DebugMacros.cpp
source/Symbol/ObjectFile.cpp
source/Symbol/SymbolVendor.cpp
source/Utility/ConvertEnum.cpp
|
(nit): "= default" (for all other similar function also)