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

Polymorphism doesn't work with SIDE_MODULE + USE_PTHREADS at all #17150

Closed
alexander-veselov opened this issue Jun 3, 2022 · 8 comments
Closed

Comments

@alexander-veselov
Copy link
Contributor

alexander-veselov commented Jun 3, 2022

It seems that polymorphism doesn't work with SIDE_MODULE + USE_PTHREADS at all (see code below):

  • strange Implementation typeid name: emsc
  • you can't call Implementation methods through pointers (neither through the base pointer nor through the derived)
  • dynamic_cast / static_cast don't work

I think this is a serious problem. Am I missing something?

Important: If you remove -sUSE_PTHREADS=1 and -pthread, then everything works.

Implementation.h

#pragma once

struct Interface
{
    virtual ~Interface() {} // for std::unique_ptr
    virtual void Foo() const = 0;
};

struct Implementation : public Interface
{
    void Foo() const override;
};

Implementation.cpp

#include "Implementation.h"

#include <iostream>

void Implementation::Foo() const
{
    std::cout << "Foo" << std::endl;
};

main.cpp

#include "Implementation.h" // separate side module (dynamic linking)

#include <memory>
#include <iostream>

int main()
{
    std::cout << typeid(Interface).name() << std::endl; // 9Interface
    std::cout << typeid(Implementation).name() << std::endl; // emsc

    Implementation().Foo(); // works

    std::unique_ptr<Interface> interfacePointer(new Implementation());
    std::unique_ptr<Implementation> implementationPointer(new Implementation());

    // All calls below cause error 'null function or function signature mismatch'
    implementationPointer->Foo();
    interfacePointer->Foo(); 
    Interface* castedPointer = static_cast<Interface*>(implementationPointer.get());

    return 0;
}

Build commands:

emcc Implementation.cpp -fPIC -pthread -sSIDE_MODULE=1 -sUSE_PTHREADS=1 -o SideModule.wasm
emcc main.cpp -fPIC -pthread -sMAIN_MODULE=1 -sUSE_PTHREADS=1 -sPROXY_TO_PTHREAD=1 -o main.html SideModule.wasm

Runtime error:

Uncaught RuntimeError: null function or function signature mismatch
@Maksim-Bozhko
Copy link

This seems like a very serious bug, do emscripten devs have any comments or suggestions, are there any plans to fix this?

@sbc100
Copy link
Collaborator

sbc100 commented Jun 7, 2022

Dynamic linking + threading is still experimental so its not unlikely this is real bug for something we don't yet have test coverage for. I'll take a look.

@goldwaving
Copy link
Contributor

I'm not having any success with dynamic linking and pthreads in a real world multithreaded app. Statically linked, everything works as expected. Dynamically linked (on load or dlopen), strange and unexpected errors always occur. These errors occur on pure C libraries, so I think the issue goes beyond polymorphism.

@sbc100
Copy link
Collaborator

sbc100 commented Jun 8, 2022

I'm working a fix this for this issue. It relates the weakly defined symbols that C++ uses for rtti info.

If you have other issues please file them.

@sbc100
Copy link
Collaborator

sbc100 commented Jun 8, 2022

Fix is in flight upstream in llvm: https://reviews.llvm.org/D127333

@Maksim-Bozhko
Copy link

Thanks for a quick fix

@alexander-veselov
Copy link
Contributor Author

Thank you so much!

@goldwaving
Copy link
Contributor

Dynamically linked C and C++ modules are working great now. Thanks!

mem-frob pushed a commit to draperlaboratory/hope-llvm-project that referenced this issue Oct 7, 2022
Back in https://reviews.llvm.org/D117412 we moved the application of
data reloctions to the wasm start function.

However, because the dynamic linker doesn't know the final addresses
at module instantiation time, this proved to be too early and the
relocations could be applied with the wrong values.

Fixes: emscripten-core/emscripten#17150

Differential Revision: https://reviews.llvm.org/D127333
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants