Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
296 views
in Technique[技术] by (71.8m points)

c++ - ConnectNamedPipe() function triggers "Debug Error! abort()" when called from within a method of a Functor that's passed as an argument to a new Thread

Error

Executing the below in Visual Studio triggers "Debug Error! abort() has been called":

if(m_handle==INVALID_HANDLE_VALUE) return(false); // no return here, therefore m_handle is valid (?)
if(!m_connected){ // some bool indicating a connection doesn't already exist

    if(ConnectNamedPipe(m_handle,NULL)==0){ // --- Abort() message triggered here ----
        // ...
    }
}

Context

The above code is part of a connectClient() method of a PipeFunctor class that overloads the function call operator (); and within that overloaded function is a call to connectClient():

void PipeFunctor::operator()() {
    connectClient(); // PipeFunctor::connectClient() called here
    // ... 
}

The connectClient() method is indirectly called via the functor passed to thread, i.e.:

PipeFunctor pipeF();
// ...
std::thread (std::ref(pipeF)); 

Hypothesis

When connectClient() is directly called (as shown below), the same offending ConnectNamedPipe() statement executes without a Debug abort() error:

PipeFunctor pipeF();
// ...
pipeF.connectClient();

This leads me to believe that it is the thread execution statement, std::thread (std::ref(pipeF));, that causes the issue downstream.

1. Is there a way I can begin a new thread by passing it a functor object that contains, and subsequently calls, the ConnectNamedPipe() function, without producing this debug abort() error?

2. What's the best way to resolve this issue?

All suggestions appreciated.

Thanks!

Additional Info:

The m_handle variable is (seemingly successfully) created from within the connectClient() (as shown below) method prior to the offending function ConnectNamedPipe() being called:

if(!pipename || *pipename==0) return(false); // no return here. pipeName is a correctly initialized LPTSTR variable

   m_handle = CreateNamedPipe(pipename,PIPE_ACCESS_DUPLEX,
                            PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
                            PIPE_UNLIMITED_INSTANCES,256*1024,256*1024,5000,NULL);

   if(m_handle==INVALID_HANDLE_VALUE){ // produces if(false)
      wprintf(L"Creating pipe '%s' failed
",pipename);
      return(false);
   }
question from:https://stackoverflow.com/questions/65920024/connectnamedpipe-function-triggers-debug-error-abort-when-called-from-wit

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

PipeFunctor pipeF(); is a function declaration (a function named pipeF taking no arguments and returning a PipeFunctor). It is not a variable declaration, like you probably intended. PipeFunctor pipeF; is a variable declaration, as is PipeFunctor pipeF{};.

In any case, when using std::thread, you are passing it a reference to pipeF. My guess is that pipeF is going out of scope and being destroyed before the thread has a chance to call its operator(). If a std::thread callback throws an uncaught exception (such as by accessing data members of an invalid PipeFunctor object), std::terminate() gets called, which in turn calls std::abort() by default.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...