mono / CppSharp

Tools and libraries to glue C/C++ APIs to high-level languages
MIT License
3.1k stars 509 forks source link

fatal error at GetCXXRecordDclFromBaseType in Parser.cpp #1750

Open r-schmitt opened 1 year ago

r-schmitt commented 1 year ago
Brief Description

We are attempting to use CppSharp to bind Pixar's USD library to C# to hopefully enable a great development environment for USD in C#

On first pass, we got about a 50% success rate, almost all the failures were here: Parser.cpp line 884

These fatal parsing errors prevent us from generating any output, but I have unable to identify what specifically is breaking at this point. Any help identifying how we can avoid this error would be awesome! I've been very happy with what we've been able to generate successfully...

OS: Windows 10

Used headers

pxr/usd/sdf/path.h pxr/usd/usd/prim.h pxr/usd/usd/stage.h

these are three examples, representing a lot of core USD functionality

Used settings

DriverOptions options = driver.Options; options.GeneratorKind = GeneratorKind.CSharp; options.Verbose = true; options.GenerationOutputMode = GenerationOutputMode.FilePerUnit;

Other settings USD was exported with the cmake flag set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) which is important for getting all the mangled names exported for bindings, but not needed for these parsing errors

tritao commented 1 year ago

Sounds like an interesting bindings.

Don't have time right now to properly repro and test this, but based on looking where the code fails, I've pushed some changes that hopefully will help with the crash: https://github.com/mono/CppSharp/pull/1751

Let me know how it goes with the new version.

r-schmitt commented 1 year ago

thanks, unfortunately that has just pushed the error to a new location:

Exception thrown: read access violation. *(clang::TemplateName::getAsTemplateDecl(...)) was nullptr.

at Parser.cpp line 901

tritao commented 1 year ago

thanks, unfortunately that has just pushed the error to a new location:

Exception thrown: read access violation. *(clang::TemplateName::getAsTemplateDecl(...)) was nullptr.

at Parser.cpp line 901

Can you try making the following changes to Parser.cpp:GetCXXRecordDeclFromTemplateName:

First try adding Name.dump(); to the start of the function, hopefully when you run it it will give you the offending piece of code that makes it crash and we can take a look at what's going on.

Then try replacing the case clang::TemplateName::Template case:

    case clang::TemplateName::Template:
    {
        if (auto TD = Name.getAsTemplateDecl())
            return dyn_cast<clang::CXXRecordDecl>(TD->getTemplatedDecl());
        else
            return nullptr;
    }

Hopefully that works around it / fixes it.

r-schmitt commented 1 year ago

Name.dump() was helpful, it looks like its coming from std::enable_if which is being used for several template functions. is there a way to ignore functions that use std::enable_ifor ignore all template functions?

still hitting the error though with the code change

r-schmitt commented 1 year ago

update, after trying to bind std::optional which hits the same error, it looks like the error is actually during the parsing of Allocator

r-schmitt commented 1 year ago

@tritao do you have any updates? we're blocked at the moment due to this, but would still very much like to use this if we can

tritao commented 1 year ago

@tritao do you have any updates? we're blocked at the moment due to this, but would still very much like to use this if we can

No updates on my side, I can try to take a look next time I got some free time, but I need a test case. It would really help if you can help get me an isolated test case that can trigger this issue.

r-schmitt commented 1 year ago

thanks, any of the three headers listed in my fist post will trigger it

tritao commented 1 year ago

Ok, those are not self contained tests, ideally we have something that is only a dozen lines or so and can be included in the test suite. Usually we would start with a self-contained header (after using the preprocessing option on the compiler, so no further includes are needed), then start removing code until we as minimal repro as possible.

r-schmitt commented 1 year ago
float getOptionalFloat(std::optional<float> optionalFloat)
{
    if(optionalFloat.has_value())
    {
        return optionalFloat.value();
    }
    else
    {
        return 0.0f;
    }
}

that should trigger it

also if we cannot fix the error, any guidance on ignoring template functions during parsing would be great

tritao commented 1 year ago

Ok cool, thanks, I will try to repro that later.

tritao commented 1 year ago

@r-schmitt Btw which VS version are you using?

r-schmitt commented 1 year ago

i built cppsharp with 2019, but im running the bindings in 2022

tritao commented 1 year ago
float getOptionalFloat(std::optional<float> optionalFloat)
{
    if(optionalFloat.has_value())
    {
        return optionalFloat.value();
    }
    else
    {
        return 0.0f;
    }
}

that should trigger it

also if we cannot fix the error, any guidance on ignoring template functions during parsing would be great

Just tried to parse this with latest CppSharp in VS2019 and can't repro it.

r-schmitt commented 1 year ago

could you outline your build process/MSVC version/LLVM version and cppsharp settings/.net version? i still get this error, so maybe its a mis-configuration somwhere in my build process

tritao commented 1 year ago

could you outline your build process/MSVC version/LLVM version and cppsharp settings? i still get this error, so maybe its a mis-configuration somwhere in my build process

I've changed the C++ version in parser options to C++17, added the above code, including #include <optional> to the test suite (VTables.Native/VTables.h specifically, just out of convenience), ran VTables.Gen and can see all of above types parsed in the AST (added a breakpoint to Preprocess and just manually expanded the variables in the debugging windows).

r-schmitt commented 1 year ago

sorry, how can i change the c++ version for the parser? i don't see an option for that

tritao commented 1 year ago

driver.ParserOptions.LanguageVersion = Parser.LanguageVersion.CPP17;

r-schmitt commented 1 year ago

thanks, still getting the same errors, will try rebuilding from scratch again

tritao commented 1 year ago

Cool, if that doesn't work, try adding driver.ParserOptions.Verbose = true; and paste the output of your include paths.

Mine are:

#include "..." search starts here:
#include <...> search starts here:
 C:\dev\CppSharp\tests\dotnet\VTables
 lib\clang\14.0.0\include
 C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.28.29910\include
 C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt
 C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\shared
 C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\um
 C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\winrt

Maybe your C++ standard library is more recent and that causes issues.

tritao commented 1 year ago

If this is still an issue, might be worth testing with the new Clang branch that comes with a newer Clang version and supports VS 2022: https://github.com/mono/CppSharp/pull/1724

r-schmitt commented 1 year ago

thanks, i've been able to test this out again and am hitting two issues

  1. no option for Verbose in ParserOptions
  2. vs2022 built with clang 18, but the parser setup is trying to find lib/clang/14/include and failing
tritao commented 1 year ago

thanks, i've been able to test this out again and am hitting two issues

  1. no option for Verbose in ParserOptions

It definitely exists: https://github.com/mono/CppSharp/blob/3c31179db1e8a4a2f008612fb005124b946cc793/examples/Parser/Parser.cs#L36

Something wrong with auto-complete maybe? Dunno.

  1. vs2022 built with clang 18, but the parser setup is trying to find lib/clang/14/include and failing

Sounds like your CppSharp.CppParser.dll might be outdated, re-compile it and make sure the new copy is in the same folder as the managed program executable.

r-schmitt commented 1 year ago

trying to set Verbose explicitly causes a compilation error for me and rebuilding CppParser.CppParser.dll still has the error pointing to clang 14 when run.

Clearly something is misconfigured, but I cannot tell what. for this branch what are the generate and build commands you recommend?

I am using the OTB ones from getting started:

sh build.sh generate -configuration Release -platform x64
sh build.sh -configuration Release -platform x64
tritao commented 1 year ago

Those should do it: https://github.com/mono/CppSharp/blob/main/.github/workflows/main.yml#L43

deadlocklogic commented 8 months ago

https://github.com/mono/CppSharp/blob/9071cd2a591d5dcb5c584d2774f60905db12ce56/src/CppParser/Parser.cpp#L877-L905 We should remove the assertion in both functions. If you are running in release mode, they won't bother anyway. But in debug mode they are buggy when you try to resolve a template parameter or a dependent type. The main purpose of these functions is to resolve the base classes of a struct/class in order to calculate the layout. In the case of a dependent type as base classes, this won't make any sense because the type can't be resolved. Check #1819, in the future layout calculation should be done on the managed side.