eclipse-cdt / cdt

Eclipse CDT™ C/C++ Development Tools
http://eclipse.org/cdt
Eclipse Public License 2.0
299 stars 197 forks source link

Enhance PE64 symbol presentation in Project Explorer #652

Closed jld01 closed 7 months ago

jld01 commented 8 months ago

The Project Explorer view presents source file name plus function and data symbols in a hierarchy of child items of an ELF object file as follows:

image

However, for PE64 object files, only the function symbols are presented:

image

We should enhance the analysis of PE64 object files to provide a presentation similar to that for ELF object files as far as possible.

PatrickTasse commented 7 months ago

Hi John,

This change breaks our unit tests in Trace Compass: https://ci.eclipse.org/tracecompass/job/tracecompass-gerrit-short-ui-only/4265/testReport/junit/org.eclipse.tracecompass.lttng2.ust.ui.swtbot.tests/FlameChartViewTest/testManipulatingMappingFiles/

The GNUPEParser64 extension has a null config extension reference, causing a NPE.

Do we perhaps have to update our project configuration? Right now we only include org.eclipse.cdt.gnu.dsf.feature.group in our target and have plug-in dependencies on org.eclipse.cdt.core and org.eclipse.cdt.core.native.

Before this change it was executing the base class implementation PEBinaryObject64.loadSymbols().

jld01 commented 7 months ago

Hi @PatrickTasse, in CDT, we generally obtain information from binary files via a call to BinaryParserConfig.getBinaryParser().

The ICConfigExtensionReference that is passed to the BinaryParserConfig constructor is deduced in CModelManager.getBinaryParser(IProject). I suggest you step through this method and determine why the ICConfigExtensionReference is null in your usage.

I hope this helps.

By the way, do you run the same test with a GNU ELF binary? I would expect a similar result.

PatrickTasse commented 7 months ago

We get our binary parsers directly from the extension registry, using code that essentially mimics what is done with:

CCorePlugin.getDefault().getBinaryParser(extension.getUniqueIdentifier())

These binary parsers all have a null config extension reference.

In our test we have a file that uses ElfParser, this one still works. Another file (a win32 executable) uses GNUPEParser64, this one was working using this method until now.

jld01 commented 7 months ago

We get our binary parsers directly from the extension registry, using code that essentially mimics what is done with:

CCorePlugin.getDefault().getBinaryParser(extension.getUniqueIdentifier())

These binary parsers all have a null config extension reference.

OK. Can you provide a link to the method (in GitLab) that looks up the binary parser @PatrickTasse?

PatrickTasse commented 7 months ago

The original code is here:

https://git.eclipse.org/c/tracecompass/org.eclipse.tracecompass.git/tree/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/callstack/FunctionNameMapper.java#n269

But I'm considering changing to this, to use a public API instead:

    /* Get all the available binary parsers */
    final List<IBinaryParser> binaryParsers = new ArrayList<>();
    IExtension[] extensions = Platform.getExtensionRegistry().
            getExtensionPoint(CCorePlugin.BINARY_PARSER_UNIQ_ID).getExtensions();
    for (IExtension extension : extensions) {
        SafeRunner.run(new ISafeRunnable() {
            @Override
            public void run() throws Exception {
                IBinaryParser binaryParser = CCorePlugin.getDefault().getBinaryParser(extension.getUniqueIdentifier());
                binaryParsers.add(Objects.requireNonNull(binaryParser));
            }

            @Override
            public void handleException(@Nullable Throwable exception) {
                Activator.logError("Error creating binary parser", exception); //$NON-NLS-1$
            }
        });
    }
jld01 commented 7 months ago

@PatrickTasse, in #665 I enhanced the GNUPEBinaryObject64 class to make use of an IGnuToolFactory in the same way that the GNUElfBinaryObject class does. So GNUPEBinaryObject64 now requires a valid ICConfigExtensionReference for correct invocation of the binutils such as addr2line like the GNUElfBinaryObject class.

If you are not able to provide an appropriate ICConfigExtensionReference in the same way as CModelManager.getBinaryParser(IProject), then one option would be for you to use PEParser64 instead of GNUPEParser64. This would mirror your use of ElfParser rather than GNUElfParser.

PatrickTasse commented 7 months ago

We're invoking the binary parsers without the use of a CProject, so I guess it's not possible to have a CConfig extension reference.

I have tried to explicitly exclude GNU binary parsers as suggested, and the test is now successful using PEParser64.

Thanks for the help!