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

Logger in Unmanaged DLL called by C# DLL crashes Oracle Simphony #3119

Open
EthanHipps opened this issue Jun 28, 2024 · 6 comments
Open

Logger in Unmanaged DLL called by C# DLL crashes Oracle Simphony #3119

EthanHipps opened this issue Jun 28, 2024 · 6 comments

Comments

@EthanHipps
Copy link

EthanHipps commented Jun 28, 2024

We've been using this logger for a while in our C++ code base without issue. Recently we ported the library to Windows so that we could compile it as a DLL that can be used by a C# DLL using DllImport. That C# DLL is used by Oracle Simphony for an Extensibility application.

We started getting the exception:

System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

We pinpointed the cause of the exception to the logger (commented out every log and the crash disappears).

We use a static class to contain the loggers (excerpts below):
loggers.h:

static Loggers &get() noexcept
{
    static Loggers instance;

    return instance;
}

std::shared_ptr<spdlog::logger> debugLogger;

loggers.cpp:

int fileSize = 1024 * 1024 * 5; // 5 MB
int maxFiles = 5;
debugLogger = spdlog::create_async<spdlog::sinks::rotating_file_sink_mt>("DebugLogger", "trace.log", fileSize, maxFiles);

This is called like so:
example.cpp

Loggers::get().debugLogger->debug("This is a debug log");

We have a c# test application for the unmanaged DLL that is created by the c++ code. Logging works without issue there, but as soon as we call it from Simphony we get the System.AccessViolationException. Sometimes it continues running, other times it crashes/freezes the whole application.

If I use basic_logger_mt/st the trace file is created but nothing is logged to it. If I use the asynchronous logger no file is created. Calling the static logger or just Loggers::get() also causes the crash.

I've tried multiple versions of the library (v. 1.11-1.14.1) and tried both the compiled and header only versions.

I've read a couple of the wikis and other issues about using the library in a DLL, but most of them have to do with destructing or calling the DLL from another c++ application. Is there anything that should be done that applies specifically to a unmanaged DLL that is used via DllImport in C#?

Any ideas or help would be appreciated.

@tt4g
Copy link
Contributor

tt4g commented Jun 28, 2024

I am not familiar with C#, but I do know that you cannot call C++ functions directly.
Instead of calling a C++ function in C#, you must expose a C function that wraps a C++ function.
Please check similar questions on StackOverflow:

@EthanHipps
Copy link
Author

@tt4g Thank you for your response. We are using a wrapper class that exposes C functions for the C# code to call, similar to the example in the the first link you provided.

Just to clarify a few things from my initial post, we have two DLLs: a C++ library, and a C# library that relies on the C++ library. We are not having any issues communicating with the C++ library nor are we trying to access the logger from the C# library. The issue we're running into is that the logger causes a System.AccessViolationException in the C# library, but only when our C# library is called from Oracle Simphony. In our test app, when we call the C# library, the logger works without issue. That's why I was asking if there is a specific way I should initialize the logger, since I don't have access to a "main" to register the logger in as shown in the "How to use spdlog in DLLs wiki".

I tried your example here, #1562 (comment), with no luck.

@tt4g
Copy link
Contributor

tt4g commented Jul 1, 2024

I don't know anything about Oracle Simphony, but if it works in testing and causes problems when run on Oracle Simphony, then I should think that the cause is Oracle Simphony.
Have you contacted Oracle Simphony support?

@EthanHipps
Copy link
Author

EthanHipps commented Jul 1, 2024

@tt4g I've reached out to them, waiting on a response. Is there a way to log from spdlog without creating any additional worker threads? Also, if it makes any difference, Simphony runs in 32bit as does all of our code.

@gabime
Copy link
Owner

gabime commented Jul 1, 2024

Is there a way to log from spdlog without creating any additional worker threads

Yes, Don’t use async logger.

If you must use async logger, it is worth trying to create the async logger directly, with a newly created thread pool object:

auto tp = std::make_shared<spdlog::details::thread_pool>(queue_size, 1);
auto logger = std::make_shared<spdlog::async_logger>("DebugLogger", some _sink,spdlog::async_overflow_policy::block);

@artemyv
Copy link

artemyv commented Jul 2, 2024

You also should not use periodic flush - since this also creates a thread inside spdlog

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