Skip to content

Transport close question #190

@Virtualer

Description

@Virtualer

Hello:

If my analysis is incorrect, please feel free to correct me, thank you so much~
:)

Whether should move Transport::Close after producer/consumer->TransportClosed() and dataProducer/dataConsumer->TransportClosed() in SendTransport::Close() and RecvTransport::Close() function?

I am using mediasoupclient in my project, but I found that when I callSendTransport::Close() andRecvTransport::Close(), a crash occurs in RecvTransport::Close().
I tried to isolate the issue by adding my own logs and found that a null pointer crash occurs atthis->dataChannel->Close()in DataConsumer::TransportClosed().

  1. Files & Functions & Logs
// Transport.cpp
void SendTransport::Close()
{
	MSC_TRACE();
	MSC_ERROR("test======send close 00");
	if (this->closed)
		return;
	MSC_ERROR("test======send close 01");
	Transport::Close();
	MSC_ERROR("test======send close 02");
	// Close all Producers.
	for (auto& kv : this->producers)
	{
		MSC_ERROR("test======send close 03");
		auto* producer = kv.second;

		producer->TransportClosed();
	}
	MSC_ERROR("test======send close 04");

	// Close all Data Producers.
	for (auto& kv : this->dataProducers)
	{
		MSC_ERROR("test======send close 05");
		auto* dataProducer = kv.second;

		dataProducer->TransportClosed();
	}
	MSC_ERROR("test======send close 06");
}

// ...

void RecvTransport::Close()
{
	MSC_TRACE();
	MSC_ERROR("test======recv close 00");
	if (this->closed)
		return;

	MSC_ERROR("test======recv close 01");
	Transport::Close();
	MSC_ERROR("test======recv close 02");
	// Close all Consumers.
	for (auto& kv : this->consumers)
	{
		MSC_ERROR("test======recv close 03");
		auto* consumer = kv.second;

		consumer->TransportClosed();
	}
	MSC_ERROR("test======recv close 04");

	// Close all DataConsumers.
	for (auto& kv : this->dataConsumers)
	{
		MSC_ERROR("test======recv close 05");
		auto* dataConsumer = kv.second;

		dataConsumer->TransportClosed();
	}
	MSC_ERROR("test======recv close 06");
}
DataConsumer.cpp
void DataConsumer::TransportClosed()
{
	MSC_TRACE();
	MSC_ERROR("test======recv close 10");
	if (this->closed)
		return;
	MSC_ERROR("test======recv close 11");
	this->closed = true;
	MSC_ERROR("test======recv close 12:%d", (this->dataChannel == nullptr));
	this->dataChannel->Close();
	MSC_ERROR("test======recv close 13:%d", (this->listener == nullptr));
	this->listener->OnTransportClose(this);
	MSC_ERROR("test======recv close 14");
}
  1. Logs
05-08 09:49:22.961 25071 25757 E mediasoupclient_core: [ERROR] Transport::Close() | test======send close 00
05-08 09:49:22.961 25071 25757 E mediasoupclient_core: [ERROR] Transport::Close() | test======send close 01
05-08 09:49:22.972 25071 25757 E mediasoupclient_core: [ERROR] Transport::Close() | test======send close 02
05-08 09:49:22.972 25071 25757 E mediasoupclient_core: [ERROR] Transport::Close() | test======send close 03
05-08 09:49:22.972 25071 25757 E mediasoupclient_core: [ERROR] Transport::Close() | test======send close 04
05-08 09:49:22.972 25071 25757 E mediasoupclient_core: [ERROR] Transport::Close() | test======send close 05
05-08 09:49:22.972 25071 25757 E mediasoupclient_core: [ERROR] Transport::Close() | test======send close 06
05-08 09:49:22.972 25071 25757 E mediasoupclient_core: [ERROR] Transport::Close() | test======recv close 00
05-08 09:49:22.972 25071 25757 E mediasoupclient_core: [ERROR] Transport::Close() | test======recv close 01
05-08 09:49:23.037 25071 25757 E mediasoupclient_core: [ERROR] Transport::Close() | test======recv close 02
05-08 09:49:23.037 25071 25757 E mediasoupclient_core: [ERROR] Transport::Close() | test======recv close 03
05-08 09:49:23.037 25071 25757 E mediasoupclient_core: [ERROR] Transport::Close() | test======recv close 04
05-08 09:49:23.037 25071 25757 E mediasoupclient_core: [ERROR] Transport::Close() | test======recv close 05
05-08 09:49:23.037 25071 25757 E mediasoupclient_core: [ERROR] DataConsumer::TransportClosed() | test======recv close 10
05-08 09:49:23.037 25071 25757 E mediasoupclient_core: [ERROR] DataConsumer::TransportClosed() | test======recv close 11
05-08 09:49:23.037 25071 25757 E mediasoupclient_core: [ERROR] DataConsumer::TransportClosed() | test======recv close 12:0
05-08 09:49:23.327 26032 26032 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
05-08 09:49:23.327 26032 26032 F DEBUG   : Build fingerprint: 'xxx'
05-08 09:49:23.327 26032 26032 F DEBUG   : Revision: '0'
05-08 09:49:23.327 26032 26032 F DEBUG   : ABI: 'arm64'
05-08 09:49:23.327 26032 26032 F DEBUG   : Timestamp: 2026-05-08 09:49:23.156671732+0800
05-08 09:49:23.327 26032 26032 F DEBUG   : Process uptime: 188s
05-08 09:49:23.327 26032 26032 F DEBUG   : Cmdline: com.test.apk
05-08 09:49:23.327 26032 26032 F DEBUG   : pid: 25071, tid: 25752, name: pc_network_thre  >>> com.test.apk <<<
05-08 09:49:23.327 26032 26032 F DEBUG   : uid: 10308
05-08 09:49:23.327 26032 26032 F DEBUG   : tagged_addr_ctrl: 0000000000000001 (PR_TAGGED_ADDR_ENABLE)
05-08 09:49:23.327 26032 26032 F DEBUG   : pac_enabled_keys: 000000000000000f (PR_PAC_APIAKEY, PR_PAC_APIBKEY, PR_PAC_APDAKEY, PR_PAC_APDBKEY)
05-08 09:49:23.327 26032 26032 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0000000000000000
05-08 09:49:23.327 26032 26032 F DEBUG   : Cause: null pointer dereference
05-08 09:49:23.327 26032 26032 F DEBUG   :     x0  0000000000000000  x1  00000077dcaac2a0  x2  0000000000000018  x3  000025ab7ac4752f
05-08 09:49:23.327 26032 26032 F DEBUG   :     x4  00ffffffffffffff  x5  0000000010bb55d0  x6  0000000000000000  x7  b4000079fb8ba5b1
05-08 09:49:23.327 26032 26032 F DEBUG   :     x8  00000000000000b0  x9  0000000000000001  x10 0000000000000000  x11 0000000000000001
05-08 09:49:23.327 26032 26032 F DEBUG   :     x12 00000000000bd12d  x13 000000007fffffff  x14 0000000010bb55d0  x15 000025ab7ac632ec
05-08 09:49:23.327 26032 26032 F DEBUG   :     x16 00058cf913bade68  x17 0000000034155555  x18 0000007785bc0000  x19 00000077c3280fe8
05-08 09:49:23.327 26032 26032 F DEBUG   :     x20 00000077dcaac350  x21 000000002e29182b  x22 00000077afda3000  x23 00000077af235630
05-08 09:49:23.327 26032 26032 F DEBUG   :     x24 00000077dcaac440  x25 00000077dcaac7a8  x26 b400007a5b8d1c70  x27 00000077dc9b4000
05-08 09:49:23.327 26032 26032 F DEBUG   :     x28 00000077dc9b0000  x29 00000077dcaac2b0
05-08 09:49:23.327 26032 26032 F DEBUG   :     lr  0009ce77af41bdc8  sp  00000077dcaac2b0  pc  00000077af5ad2d0  pst 0000000080001000
05-08 09:49:23.327 26032 26032 F DEBUG   : 6 total frames
05-08 09:49:23.327 26032 26032 F DEBUG   : backtrace:
05-08 09:49:23.327 26032 26032 F DEBUG   :       #00 pc 00000000009032d0  /data/app/~~CJ-5GgnT2OeEw5aOu986oA==/com.test.apk-2dX7IAoVuygVF5FZWQEIuQ==/base.apk!libs.so (offset 0x827000) (BuildId: 73f1c95f7eafb58159b2918f51dcad400760291a)
05-08 09:49:23.327 26032 26032 F DEBUG   :       #01 pc 0000000000771dc4  /data/app/~~CJ-5GgnT2OeEw5aOu986oA==/com.test.apk-2dX7IAoVuygVF5FZWQEIuQ==/base.apk!libs.so (offset 0x827000) (BuildId: 73f1c95f7eafb58159b2918f51dcad400760291a)
05-08 09:49:23.327 26032 26032 F DEBUG   :       #02 pc 0000000000770bc0  /data/app/~~CJ-5GgnT2OeEw5aOu986oA==/com.test.apk-2dX7IAoVuygVF5FZWQEIuQ==/base.apk!libs.so (offset 0x827000) (BuildId: 73f1c95f7eafb58159b2918f51dcad400760291a)
05-08 09:49:23.327 26032 26032 F DEBUG   :       #03 pc 000000000077221c  /data/app/~~CJ-5GgnT2OeEw5aOu986oA==/com.test.apk-2dX7IAoVuygVF5FZWQEIuQ==/base.apk!libs.so (offset 0x827000) (BuildId: 73f1c95f7eafb58159b2918f51dcad400760291a)
05-08 09:49:23.327 26032 26032 F DEBUG   :       #04 pc 0000000000082858  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+232) (BuildId: 2898012bcb41d8c8cb2dc5de2cc9ae45)
05-08 09:49:23.327 26032 26032 F DEBUG   :       #05 pc 0000000000075730  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 2898012bcb41d8c8cb2dc5de2cc9ae45)
  1. Calling sequence
    Just like this:
RecvTransport::Close()
│
├── ① Transport::Close()
│       └── handler->Close()
│            └── PeerConnection::Close()
│                 ├── ICE Transport <- closed
│                 ├── DTLS Transport <- closed
│                 └── SCTP Transport <-Start asynchronous destruction <- network thread start clean
│
├── ② consumer->TransportClosed() × N   <- PeerConnection closed
│
├── ③ dataConsumer->TransportClosed()
│       └── dataChannel->Close()
│            └── notify network thread DataChannel close task
│                     └── call destoryed of SCTP Transport in ①
│                          └── 💥 SIGSEGV

Same as SendTransport.

  1. dataChannel
    why crash but test======recv close 12:0 means this->dataChannel not a null pointer. I think it's because dataChanneltype is webrtc::scoped_refptr, same as std::shared_ptr, when crash, dataChannel point object still alive, but SCTP has been destoryed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions