boost log working in exe but crashing in dll

166 Views Asked by At

I have developed an application (application1) that uses boost::log with severity_channel_logger_mt and two sinks (syslog_backend & text_file_backend).

When I run the application as an .exe, the sinks work fine and I am able to see log text files generate from messages being passed across a network, but when I link application1 as a .dll inside of another application (mainapp), I get the following errors after about 20 seconds:

Exception thrown at 0x00007FFA9E03CD29 in mainapp.exe: Microsoft C++ exception: boost::wrapexcept<boost::system::system_error> at memory location 0x000000F9BD9FF220.
Exception thrown at 0x00007FFA9E03CD29 in mainapp.exe: Microsoft C++ exception: [rethrow] at memory location 0x0000000000000000.
Exception thrown at 0x00007FFA9E03CD29 in mainapp.exe: Microsoft C++ exception: boost::wrapexcept<boost::system::system_error> at memory location 0x000000F9BD9FF220.
Exception thrown at 0x00007FFA9E03CD29 in mainapp.exe: Microsoft C++ exception: [rethrow] at memory location 0x0000000000000000.
Exception thrown at 0x00007FFA9E03CD29 in mainapp.exe: Microsoft C++ exception: boost::wrapexcept<boost::system::system_error> at memory location 0x000000F9BD9FF220.
Exception thrown at 0x00007FFA9E03CD29 in mainapp.exe: Microsoft C++ exception: [rethrow] at memory location 0x0000000000000000.
Exception thrown at 0x00007FFA9E03CD29 in mainapp.exe: Microsoft C++ exception: boost::wrapexcept<boost::system::system_error> at memory location 0x000000F9BD9FF220.

After debugging, the exception happens in basic_sink_frontend.hpp and core.hpp between these two calls:

basic_sink_frontend.hpp

backend.consume(rec, context->m_FormattedRecord);

core.hpp

BOOST_FORCEINLINE void push_record(BOOST_RV_REF(record) rec)
{
    push_record_move(static_cast< record& >(rec));
}

I have verified that the "rec" variable is not NULL. The application1 DLL loads wihout error and I am able to run application1 functions from mainapp. I still see message being passed across network from syslog sink, however text_file sink logs are not generated... I built boost as a shared library and have the following libs in boost_1_80_0/stage/lib: boost_log_setup-vc142-mt-x64-1_80 boost_log-vc142-mt-gd-x64-1_80 boost_log-vc142-mt-x64-1_80

Snippets from my code on how I use the loggers and sinks are below. Application1 uses boost::log and MainApp loads Application1 as DLL:

Application1:

#define DEFAULT_PORT 13000
#define DEFAULT_PORT_STRING "13000"
#define DEFAULT_IP "127.0.0.1"

enum class severity_levels
{
    info,
    warning,
    error
};

void Application1::init_builtin_syslog()
{

    // Create a syslog sink
    boost::shared_ptr< sinks::synchronous_sink< sinks::syslog_backend > > sys_sink(
        new sinks::synchronous_sink< sinks::syslog_backend >());
    
    sys_sink->set_formatter
    (
        expr::stream << "Application 1 Log - ID: " << expr::attr< unsigned int >("RecordID")
            << "| " << expr::attr< severity_levels >("Severity") << ": " << expr::smessage
    );
    
    // We'll have to map our custom levels to the syslog levels
    sinks::syslog::custom_severity_mapping< severity_levels > mapping("Severity");
    mapping[severity_levels::info] = sinks::syslog::info;
    mapping[severity_levels::warning] = sinks::syslog::warning;
    mapping[severity_levels::error] = sinks::syslog::critical;
    
    sys_sink->locked_backend()->set_severity_mapper(mapping);
    
    #if !defined(BOOST_LOG_NO_ASIO)
        // Set the remote address to send syslog messages to
        sys_sink->locked_backend()->set_target_address(DEFAULT_IP, DEFAULT_PORT);
    #endif
    
    //Create a text file sink
    boost::shared_ptr< sinks::synchronous_sink< sinks::text_file_backend > > file_sink(
        new sinks::synchronous_sink< sinks::text_file_backend >(
            keywords::file_name = "application1.log",  // file name pattern
            keywords::target_file_name = "application1_%Y%m%d_%H%M%S_%2N.log",           
            keywords::rotation_size = 16384                                 
            )); 
    // Set up where the rotated files will be stored
    file_sink->locked_backend()->set_file_collector(sinks::file::make_collector(
        keywords::target = "logs",                              
        keywords::max_size = 64 * 1024 * 1024,                  
        keywords::min_free_space = 100 * 1024 * 1024,           
        keywords::max_files = 512                           
        ));
    
    // Upon restart, scan the target directory for files matching the file_name pattern
    file_sink->locked_backend()->scan_for_files();
    
    file_sink->set_formatter
    (
        expr::format("%1% Application 1 Log - ID: %2% | %3% : \"%4%\"")
        % expr::attr< boost::posix_time::ptime >("TimeStamp")
        % expr::attr< unsigned int >("RecordID")
        % expr::attr< severity_levels >("Severity")
        % expr::smessage
    );
    
    // Add the sinks to the core
    logging::core::get()->add_sink(sys_sink);
    logging::core::get()->add_sink(file_sink);
    
    // Add logging attributes
    logging::core::get()->add_global_attribute("RecordID", attrs::counter< unsigned int >());
    logging::core::get()->add_global_attribute("TimeStamp", attrs::utc_clock());

}

int start()
{
   init_builtin_syslog();
   src::severity_channel_logger_mt\< severity_levels \> lg(keywords::severity = severity_levels::info, keywords::channel = "Application 1");

   for (int i = 0; i \< 10000; ++i)
   {
      BOOST_LOG_SEV(lg, severity_levels::info) \<\< infoLog;
      if(runexe) std::cout \<\< "App1 sent: " \<\< infoLog \<\< std::endl;
      boost::this_thread::sleep_for(boost::chrono::milliseconds(1000));
   }
return 0;
}

MainApp:

bool loadedApp1 = false; 
std::atomic<bool> startApp1 = true;  
std::atomic<char*> app1Err((char*)""); 

HINSTANCE app1dll;
void printError( const TCHAR* msg );

typedef void (*MYPROC2)(std::atomic<bool>&, std::atomic<char*>&);
MYPROC2 app1start;

int main()
{

std::cout << "Starting application 1... " << std::endl;
        try
        {
            app1dll = LoadLibrary(TEXT("application1.dll"));
            if(app1dll == NULL)
            {
                std::cerr << "Application 1 DLL load library failure." << GetLastError() << '\n';
                loadedApp1 = false;
            }
            else
            {
                loadedApp1 = true;
                 app1start = (MYPROC2) GetProcAddress(app1dll, MAKEINTRESOURCEA(1)); 
                if (NULL != app1start) 
                {
                    std::thread t1(app1start, std::ref(startApp1), std::ref(app1Err));
                    t1.detach();
                    std::this_thread::sleep_for(std::chrono::milliseconds(4000));
                }      
                if(startApp1.load() == false)
                {
                    std::cout << "Error starting Application 1: " << app1Err.load() << std::endl;
                }
            }
}
 catch(const std::exception& e)
{
    std::cerr << e.what() << '\n';
    return 1;
}
return 0;
}
0

There are 0 best solutions below