Skip to content
This repository has been archived by the owner on Jun 23, 2022. It is now read-only.

thread safe problem in singleton #404

Closed
levy5307 opened this issue Feb 24, 2020 · 0 comments
Closed

thread safe problem in singleton #404

levy5307 opened this issue Feb 24, 2020 · 0 comments

Comments

@levy5307
Copy link
Contributor

levy5307 commented Feb 24, 2020

I had been refactoring the code in rdsn recently. When create a class named logger_proxy, I encountered the thread safe problem in singleton.
The logger_proxy inherit from class singleton:

class logger_proxy : public singleton<logger_proxy>
{
}

In dsn_nfs_test, when the main thread is exit, It will send SIGSEGV(sig id = 11), so the child thread will run the code in native_linux_aio_provider::get_event, line 26, to print a warn log.

void native_linux_aio_provider::get_event()
{
    struct io_event events[1];
    int ret;
 
    task::set_tls_dsn_context(node(), nullptr);
 
    const char *name = ::dsn::tools::get_service_node_name(node());
    char buffer[128];
    sprintf(buffer, "%s.aio", name);
    task_worker::set_name(buffer);
 
    while (true) {
        if (dsn_unlikely(!_is_running.load(std::memory_order_relaxed))) {
            break;
        }
        ret = io_getevents(_ctx, 1, 1, events, NULL);
        if (ret > 0) // should be 1
        {
            dassert(ret == 1, "io_getevents returns %d", ret);
            struct iocb *io = events[0].obj;
            complete_aio(io, static_cast<int>(events[0].res), static_cast<int>(events[0].res2));
        } else {
            // on error it returns a negated error number (the negative of one of the values listed
            // in ERRORS
            dwarn("io_getevents returns %d, you probably want to try on another machine:-(", ret);
        }
    }
}

But it produce a coredump when the child thread visit the instance of logger_proxy, which means the instance has already been destroyed.
Here is the coredump message and the code of dsn_logv function:

#0  0x0000000000000000 in ?? ()
#1  0x000055d1ab0ecb78 in dsn::join_point<void, dsn::sys_exit_type, dsn::join_point_unused_type, dsn::join_point_unused_type>::execute (p1=dsn::SYS_EXIT_EXCEPTION, 
    this=<optimized out>) at /home/mi/workspace/pegasus/rdsn/include/dsn/utility/join_point.h:372
#2  dsn::utils::coredump::write () at /home/mi/workspace/pegasus/rdsn/src/core/core/coredump.posix.cpp:63
#3  <signal handler called>
#4  0x0000000000000000 in ?? ()
#5  0x000055d1ab084e29 in dsn_logv (file=0x55d1ab1c4f7f "native_aio_provider.linux.cpp", 
    function=0x55d1ab1c5100 <dsn::tools::native_linux_aio_provider::get_event()::__FUNCTION__> "get_event", line=128, log_level=LOG_LEVEL_WARNING, 
    fmt=0x55d1ab1c4ec8 "io_getevents returns %d, you probably want to try on another machine:-(", args=args@entry=0x7f39d1ebe310)
    at /home/mi/workspace/pegasus/rdsn/src/core/core/logger.cpp:103
#6  0x000055d1ab084f31 in dsn_logf (file=file@entry=0x55d1ab1c4f7f "native_aio_provider.linux.cpp", 
    function=function@entry=0x55d1ab1c5100 <dsn::tools::native_linux_aio_provider::get_event()::__FUNCTION__> "get_event", line=line@entry=128, 
    log_level=log_level@entry=LOG_LEVEL_WARNING, fmt=fmt@entry=0x55d1ab1c4ec8 "io_getevents returns %d, you probably want to try on another machine:-(")
---Type <return> to continue, or q <return> to quit---  
   asus/rdsn/src/core/core/logger.cpp:115
#7  0x000055d1ab15e80e in dsn::tools::native_linux_aio_provider::get_event (this=0x55d1ada38450)
    at /home/mi/workspace/pegasus/rdsn/src/core/tools/common/native_aio_provider.linux.cpp:128
#8  0x00007f39d2b2966f in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#9  0x00007f39d2dfc6db in start_thread (arg=0x7f39d1ec0700) at pthread_create.c:463
#10 0x00007f39d258488f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

dsn_logv:

DSN_API void dsn_logv(const char *file,
                      const char *function,
                      const int line,
                      dsn_log_level_t log_level,
                      const char *fmt,
                      va_list args)
{
    ::dsn::utils::logger *log = &dsn::utils::logger_proxy::instance();
    log->logv(file, function, line, log_level, fmt, args);
}
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant