Subject: [BUG] Crash in FFM when calling native function with std::make_unique<RtcManager>

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Tue Apr 8 08:56:04 UTC 2025


Hi,
I still have the feeling that we're looking at several pieces -- but 
missing the full picture. We know that:

* this is a custom C++ library
* there is a C header which exports some of the C++ symbols with `extern 
"C"`
* this C++ library seems to depend on the datachannel library

We haven't seen how the Java side does the calling.

It would be really helpful if there was a self-contained repository 
somewhere we could look at to try and reproduce (and better understand) 
this issue.

As for this code, `make_unique` creates a new RtcManager object -- so 
maybe something is up with the constructor call -- but hard to say what 
could be (the issue could also be completely unrelated).

If you remove most of the code from `createRtcContext` and just leave this

```
rtcManager = std::make_unique<RtcManager>()
```

Does it still crash there?

Maurizio

On 08/04/2025 01:51, bai li wrote:
> The createRtcContext function is like this:
> void createRtcContext(const char* localId,int logLevel,IceConfig* iceConfig,DataChannelConfig* dataChannelConfig) {
>      std::cout<< "1" << std::endl;
>      int expected =0;
>      bool success = state.compare_exchange_strong(expected,1);
>      if (!success)return;
>      if (localId ==nullptr)return;
>      if (iceConfig ==nullptr)return;
>      if (dataChannelConfig ==nullptr)return;
>      std::cout<< "2" << std::endl;
>      std::string id =std::string(localId);
>      std::cout<< "2 1" << " " << id<< std::endl;
>      std::make_unique<int>(3);
>      std::cout<< "2 1 1" << std::endl;
>      rtcManager= std::make_unique<RtcManager>(); // Crash here! std::cout<< "2 1 2" << std::endl;
>      rtcManager->setLocalId(id);
>      std::cout<< "2 2" << std::endl;
>      rtcManager->initLogger(logLevel);
>      std::cout<< "2 3" << std::endl;
>      IceModel iceModel;
>      std::cout<< "2 4" << std::endl;
>      iceModel.setNoStun(iceConfig->noStun);
>      iceModel.setStunServer(std::string(iceConfig->stunServer));
>      iceModel.setStunPort(iceConfig->stunPort);
>      iceModel.setUdpMux(iceConfig->udpMux);
>      iceModel.setWebSocketServer(std::string(iceConfig->webSocketServer));
>      iceModel.setWebSocketPort(iceConfig->webSocketPort);
>      std::cout<< "2 5" << std::endl;
>      auto dataChannelListener =DataChannelListener::Builder()
>              .withOnOpen(dataChannelConfig->onOpen)
>              .withOnClosed(dataChannelConfig->onClosed)
>              .withOnTextMessage(dataChannelConfig->onTextMessage)
>              .withOnBinaryMessage(dataChannelConfig->onBinaryMessage)
>              .build();
>      std::cout<< "2 6" << std::endl;
>      std::shared_ptr<DataChannelListener> dcListener = std::move(dataChannelListener);
>      std::cout<< "3" << std::endl;
>      rtcManager->initDataChannelListener(dcListener);
>      std::cout<< "4" << std::endl;
>      std::unique_ptr<WebSocketHelper> webSocketHelper = rtcManager->connectToSignalingServer(iceModel);
>      std::cout<< "5" << std::endl;
>      while (state.load() ==1) {
>          std::this_thread::yield();
>      }
>      std::cout<< "6" << std::endl;
> }
>
> On Mon, Mar 31, 2025 at 5:26 PM bai li <k3315368931 at gmail.com> wrote:
>
>     Hi Panama team,
>
>     I’m using the Java FFM API in JDK 21 to call a C++ dynamic library
>     function, `void createRtcContext(const char* localId, int
>     logLevel, IceConfig* iceConfig, DataChannelConfig*
>     dataChannelConfig)`. The function can be invoked, but it crashes
>     when executing `std::make_unique<RtcManager>()` inside the
>     function. The same C++ code runs without any issues when executed
>     independently. The `RtcManager` class is roughly defined as follows:
>
>     ```cpp
>     class RtcManager {
>     private:
>         std::string localId;
>         rtc::Configuration config;
>         std::unordered_map<std::string,
>     std::shared_ptr<rtc::PeerConnection>> peerConnectionMap;
>         std::unordered_map<std::string,
>     std::shared_ptr<rtc::DataChannel>> dataChannelMap;
>         std::shared_ptr<rtc::WebSocket> ws =
>     std::make_shared<rtc::WebSocket>();
>         std::shared_ptr<DataChannelListener> dataChannelListener =
>     nullptr;
>     public:
>         explicit RtcManager(const std::string& id) : localId(id) {}
>     };
>     The C++ code is compiled with MSVC 2022. Here’s the crash log from
>     the console:
>     # A fatal error has been detected by the Java Runtime Environment:
>     #
>     #  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at
>     pc=0x00007ffb0ca62f58, pid=22096, tid=26348
>     #
>     # JRE version: Java(TM) SE Runtime Environment (21.0.6+8) (build
>     21.0.6+8-LTS-188)
>     # Java VM: Java HotSpot(TM) 64-Bit Server VM (21.0.6+8-LTS-188,
>     mixed mode, sharing, tiered, compressed oops, compressed class
>     ptrs, g1 gc, windows-amd64)
>     # Problematic frame:
>     # C  [msvcp140.dll+0x12f58]
>     #
>     # No core dump will be written. Minidumps are not enabled by
>     default on client versions of Windows
>     #
>     # An error report file with more information is saved as:
>     # E:\projects\backend-projects\test\hs_err_pid22096.log
>     [0.236s][warning][os] Loading hsdis library failed
>     #
>     # If you would like to submit a bug report, please visit:
>     # https://bugreport.java.com/bugreport/crash.jsp
>     # The crash happened outside the Java Virtual Machine in native code.
>     # See problematic frame for where to report the bug.
>     #
>     Thanks
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/panama-dev/attachments/20250408/77cb20ca/attachment-0001.htm>


More information about the panama-dev mailing list