WebRtc Native-Crashed when I call peerconnection->Close()

775 views
Skip to first unread message

Yunke Zou

unread,
Jun 27, 2018, 11:27:51 PM6/27/18
to discuss-webrtc
Hi,

  I'm wondering how to close or destruct a PeerConnectionInterface object? It crashed when I'm trying to do so.

  The crash step is:

  1. PeerConnectionInterface->Close() or ~PeerConnectionInterface() is called.

  2. The webrtc_session_desc_factory_.reset() is called.

  3. The FailPendingRequests(const std::string& reason) which is in ~WebRtcSessionDescriptionFactory() is called.

  4. Crashed in the while loop.


  I have an object declared like this:

    rtc::scoped_refptr<webrtc::PeerConnectionInterface> _peerConnection;


  It works fine after I create the PeerConnectionInterface by factory.


  However, when the session is over and I try to call _peerConnection->Close(); The program crashed. And I also try to call _peerConnection.release()->Release(); Crashed as well.


  I print logs in PeerConnection.cc which is from the source code of WebRtc, and find that it crashed here, which is in Close() function and ~PeerConnection() function:

    webrtc_session_desc_factory_.reset(); //PeerConnection.cc


  The declare is:

    std::unique_ptr<WebRtcSessionDescriptionFactory> webrtc_session_desc_factory_;


  So I continue to log in WebRtcSessionDescriptionFactory.cc, the ~WebRtcSessionDescriptionFactory() function. Crashed in this function:FailPendingRequests(). Entered the FailPendingRequests() function:


  FailPendingRequests(const std::string& reason)

  {

    RTC_DCHECK(signaling_thread_->IsCurrent());

    while (!create_session_description_requests_.empty())

    {

         const CreateSessionDescriptionRequest& request = create_session_description_requests_.front();

         //Crashed here in third or fourth loop

         PostCreateSessionDescriptionFailed(request.observer, ((request.type == CreateSessionDescriptionRequest::kOffer) ?

             "CreateOffer" : "CreateAnswer") + reason);

         create_session_description_requests_.pop();

    }

  }


I will be really grateful for any suggestion!

Taylor Brandstetter

unread,
Jun 28, 2018, 1:26:24 PM6/28/18
to discuss-webrtc
Can you attach a debugger to see specifically where it's crashing? I wouldn't expect PostCreateSessionDescriptionFailed to crash, since it's only "posting" a message to the current thread (to be processed asynchronously). Unless "signaling_thread_" has been destroyed prematurely, I'm not sure how this would fail.

--

---
You received this message because you are subscribed to the Google Groups "discuss-webrtc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to discuss-webrtc+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/discuss-webrtc/0a2a7a19-faee-4c4e-94e0-7be136be4175%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Yunke Zou

unread,
Jun 28, 2018, 9:20:04 PM6/28/18
to discuss-webrtc
Hi,

I know it is just post to thread, that's why I feel confused. It's not crashed in first loop! I tried to just release the webrtc_session_desc_factory_, instead of calling reset, which means I haven't released the memory. The following steps continue smoothly, and it seems destruct the peerconnectionInterface successfully (Obviously not). And when I'm trying to create a new peerconnectionInterface from factory after the destruction, crashed as I expected. Maybe is that any way to check if signaling_thread_ is still working or to track the posted signal?
As I try to log above and below the PostCreateSessionDescriptionFailed(request.observer, ((request.type == CreateSessionDescriptionRequest::kOffer) ? "CreateOffer" : "CreateAnswer") + reason);

The last log shows the log above, but the below log below doesn't show.

I guess if the way I create peerconnectionInterface is not correct. I followed the conductor.cc in example document, first create factory:
    _peerConnectionFactory = webrtc::CreatePeerConnectionFactory(
                nullptr /* network_thread */, nullptr /* worker_thread */,
                nullptr /* signaling_thread */, nullptr /* default_adm */,
                webrtc::CreateBuiltinAudioEncoderFactory(),
                webrtc::CreateBuiltinAudioDecoderFactory(),
                webrtc::CreateBuiltinVideoEncoderFactory(),
                webrtc::CreateBuiltinVideoDecoderFactory(), nullptr /* audio_mixer */,
                nullptr /* audio_processing */);

Then create peerconnectionInterface:
    webrtc::PeerConnectionInterface::RTCConfiguration config;
    config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
    config.enable_dtls_srtp = dtls;
    webrtc::PeerConnectionInterface::IceServer server;
    server.uri = GetPeerConnectionString();
    qDebug() << QString::fromStdString(server.uri);
    config.servers.push_back(server);

    _peerConnection = _peerConnectionFactory->CreatePeerConnection(
                config, nullptr, nullptr, this);

Add tracks:
    if (!_peerConnection->GetSenders().empty()) {
        return;  // Already added tracks.
    }

    rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
                _peerConnectionFactory->CreateAudioTrack(
                    kAudioLabel, _peerConnectionFactory->CreateAudioSource(nullptr)));
    auto result_or_error = _peerConnection->AddTrack(audio_track, {kStreamId});
    if (!result_or_error.ok()) {
        qDebug() << "Failed to add audio track to PeerConnection";
        RTC_LOG(LS_ERROR) << "Failed to add audio track to PeerConnection: "
                          << result_or_error.error().message();
    }

    std::unique_ptr<cricket::VideoCapturer> video_device =
            OpenVideoCaptureDevice();
    if (video_device) {
        rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track_(
                    _peerConnectionFactory->CreateVideoTrack(
                        kVideoLabel, _peerConnectionFactory->CreateVideoSource(
                            std::move(video_device), nullptr)));
        //        main_wnd_->StartLocalRenderer(video_track_);

        result_or_error = _peerConnection->AddTrack(video_track_, {kStreamId});
        if (!result_or_error.ok()) {
            qDebug() << "Failed to add video track to PeerConnection";
            RTC_LOG(LS_ERROR) << "Failed to add video track to PeerConnection: "
                              << result_or_error.error().message();
        }
    } else {
        qDebug() << "OpenVideoCaptureDevice failed";
        RTC_LOG(LS_ERROR) << "OpenVideoCaptureDevice failed";
    }

These are my create steps. BTW, my peerconnection has only remote offer and local answer. I used the datachannel. What's more, what I haven't followed the constructor.cc is the loopback (As I can't understand what's this used for). Hope I have offered enough information.

Longer
To unsubscribe from this group and stop receiving emails from it, send an email to discuss-webrt...@googlegroups.com.

Yunke Zou

unread,
Jun 29, 2018, 5:30:02 AM6/29/18
to discuss-webrtc
Hi,

I have a new discovery. I'm working with Qt. I found that when I destruct the peerconnectionInterface just after initiate it, it works without crash, like here:
    qDebug() << _peerconnection->initial();

    if(_peerConnection.get())
        _peerConnection = nullptr;
    if(_peerConnectionFactory.get())
        _peerConnectionFactory = nullptr;

And then, I change the place where I destruct the _peerconnection. After I use the QWebSocket(in Qt framework) to connect with signal server, and create a room, I destruct the _peerconnection at the moment when I recieve a "create success" message from server. Obviously, the _peerconnection has not been changed or even called in this step. However, it crashed.
So what I mean is:
1. I can destruct peerconnectionInterface without crash before I use QWebSocket to connect with server.
2. I destruct peerconnectionInterface( it is not changed and none of it's function is called during the time) crashed, after I use QWebSocket to connect with server.

Then I guess if it's multi-thread problem, because QWebSocket works in main thread which I initiate peerconnectionInterface and destruct it. Then I move QWebSocket to run in another thread, and destruct peerconnectionInterface in the main thread.However, crashed.

Now I have no idea with the problem if there is something wrong, would you have any suggestion? Many thanks.

Longer



On Friday, June 29, 2018 at 1:26:24 AM UTC+8, Taylor Brandstetter wrote:
To unsubscribe from this group and stop receiving emails from it, send an email to discuss-webrt...@googlegroups.com.

Taylor Brandstetter

unread,
Jun 29, 2018, 1:44:16 PM6/29/18
to discuss-webrtc
The documentation doesn't make this very clear, but if you pass in null for "signaling_thread", the thread on which CreatePeerConnectionFactory was called will be used as the signaling thread, and you need to pump messages on that thread yourself (using "rtc::Thread::Current()->Run()" or "rtc::Thread::Current()->ProcessMessages()"). Are you doing that? If not, does the problem go away if you pass in a "new rtc::Thread()"?

To unsubscribe from this group and stop receiving emails from it, send an email to discuss-webrtc+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/discuss-webrtc/ac104f2d-1c82-4b33-a2c7-854ba04007e5%40googlegroups.com.

Yunke Zou

unread,
Jul 6, 2018, 3:41:00 AM7/6/18
to discuss-webrtc
Hi,

Maybe I find out the reason. Here generate a request object with function "const CreateSessionDescriptionRequest& request = create_session_description_requests_.front();", and then pass the request.observer to a CreateSessionDescriptionMsg object. However, the observer is nullptr. I guess this causes the crash. Why is the observer equals to nullptr????

Longer

Yunke Zou

unread,
Jul 10, 2018, 12:03:32 AM7/10/18
to discuss-webrtc
Hi,

Well, the issue has been solved. Because there is something wrong in webrtcsessiondescriptionfactory.cc file.

In the function void WebRtcSessionDescriptionFactory::SetCertificate(const rtc::scoped_refptr<rtc::RTCCertificate>& certificate);

void WebRtcSessionDescriptionFactory::SetCertificate(
    const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {
  RTC_DCHECK(certificate);
  RTC_LOG(LS_VERBOSE) << "Setting new certificate.";

  certificate_request_state_ = CERTIFICATE_SUCCEEDED;
  SignalCertificateReady(certificate);

  transport_desc_factory_.set_certificate(certificate);
  transport_desc_factory_.set_secure(cricket::SEC_ENABLED);

  while (!create_session_description_requests_.empty()) {
    if (create_session_description_requests_.front().type ==
        CreateSessionDescriptionRequest::kOffer) {
      InternalCreateOffer(create_session_description_requests_.front());
    } else {
      InternalCreateAnswer(create_session_description_requests_.front());
    }
    create_session_description_requests_.pop();                    //The pop option should be here
  }
  //The pop option is here in native code, however it should be in the while loop.
}

The function pop the queue in a wrong way, that caused the crash! Move the pop option into the while loop can solve the issue!

Many thanks!

Longer
Reply all
Reply to author
Forward
0 new messages