Code Monkey home page Code Monkey logo

crash-repro's Introduction

Steps to reproduce a crash in node-datachannel


Environment

  • Browser
    • Windows Chrome Version 115.0.5790.173 (Official Build) (64-bit)
  • Node
    • node-datachannel version: 0.4.3
    • Docker image node:18.16.1-bullseye-slim running on DigitalOcean droplet (Debian do-kube-1.27.2-do.0)
    • uname -a inside Docker container inside Kuberenetes Pod with hostNetwork: true: Linux do-sfo3-0-dev-swarm-drone-demand-node-pool-f9ed0 6.1.0-0.deb11.6-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.15-1~bpo11+1 (2023-03-16) x86_64 GNU/Linux

1. Open a new Chrome browser window and open its DevTools Console. Please note that opening a new Chrome window before running the following steps seems to increase the probability of reproducing the crash (though this may not be true).

2. Run the following snippet in a Chrome browser DevTools Console:

const iceServers = [
	{ urls: 'stun:stun1.l.google.com:19302' },
	{ urls: 'stun:stun2.l.google.com:19302' },
	{ urls: 'stun:stun3.l.google.com:19302' },
	{ urls: 'stun:stun4.l.google.com:19302' },
];

const peerConnection = new RTCPeerConnection({
	iceServers,
	iceTransportPolicy: 'all',
});

let dataChannel;

peerConnection.onconnectionstatechange = ev => {
	const { connectionState } = peerConnection;
	console.log(`peerConnection.onconnectionstatechange(): connectionState: ${connectionState}`);
};
peerConnection.ondatachannel = ev => {
	console.log('peerConnection.ondatachannel()');

	dataChannel = ev.channel;
	dataChannel.onopen = ev => {
		console.log('dataChannel.onopen()');

		peerConnection.close(); // Close RTCPeerConnection immediately after RTCDataChannel opens
	};
	dataChannel.onmessage = ev => {
		console.log(`dataChannel.onmessage(): ev.data: ${ev.data}`);
	};
	dataChannel.onclose = ev => {
		console.log(`dataChannel.onclose()`);
	};
	dataChannel.onerror = ev => {
		console.log(`dataChannel.onerror(): ev.data: ${ev.data}`);
	};
};
peerConnection.onicecandidate = ev => {
	const { candidate } = ev;
	console.log('peerConnection.onicecandidate(): candidate:', candidate);

	console.log(`COPY LAST ONE PRINTED AS THE FINAL ANSWER: ${JSON.stringify(peerConnection.localDescription)}\n`);
};
peerConnection.oniceconnectionstatechange = ev => {
	const { iceConnectionState } = peerConnection;
	console.log(`peerConnection.oniceconnectionstatechange(): iceConnectionState: ${iceConnectionState}`);
};
peerConnection.onicegatheringstatechange = ev => {
	const { iceGatheringState } = peerConnection;
	console.log(`peerConnection.onicegatheringstatechange(): iceGatheringState: ${iceGatheringState}`);
};
peerConnection.onsignalingstatechange = ev => {
	const { signalingState } = peerConnection;
	console.log(`peerConnection.onsignalingstatechange(): signalingState: ${signalingState}`);
};

3. Run the following snippet in a Node REPL:

const { default: nodeDataChannel } = await import('node-datachannel');

const iceServers = [
	{
		hostname: 'stun:stun1.l.google.com',
		port: 19302,
	},
	{
		hostname: 'stun:stun2.l.google.com',
		port: 19302,
	},
	{
		hostname: 'stun:stun3.l.google.com',
		port: 19302,
	},
	{
		hostname: 'stun:stun4.l.google.com',
		port: 19302,
	},
];

const peerConnection = new nodeDataChannel.PeerConnection('', {
	iceServers,
	iceTransportPolicy: 'all',
});
peerConnection.onStateChange(state => {
	console.log(`peerConnection.onStateChange(): state: ${state}`);
});
peerConnection.onSignalingStateChange(state => {
	console.log(`peerConnection.onSignalingStateChange(): state: ${state}`);
});
peerConnection.onGatheringStateChange(state => {
	console.log(`peerConnection.onGatheringStateChange(): state: ${state}`);
});
peerConnection.onLocalDescription((sdp, type) => {
	console.log(`peerConnection.onLocalDescription(): sdp: ${sdp}, type: ${type}`);
});
peerConnection.onLocalCandidate((candidate, mid) => {
	console.log(`peerConnection.onLocalCandidate(): candidate: ${candidate}, mid: ${mid}`);

	console.log(`COPY LAST ONE PRINTED AS THE FINAL OFFER: ${JSON.stringify(peerConnection.localDescription())}\n`);
});

const dataChannel = peerConnection.createDataChannel('', {
	ordered: false,
	maxRetransmits: 0,
});
dataChannel.onOpen(() => {
	console.log('dataChannel.onOpen()');
});
dataChannel.onMessage(msg => {
	console.log('dataChannel.onMessage(): msg:', msg);
});
dataChannel.onClosed(() => {
	console.log('dataChannel.onClosed()');

	// These lines setting callbacks appear to cause the crash
	peerConnection.onStateChange(state => {});
	peerConnection.onSignalingStateChange(state => {});
	peerConnection.onGatheringStateChange(state => {});
	peerConnection.onLocalDescription((sdp, type) => {});
	peerConnection.onLocalCandidate((candidate, mid) => {});

	peerConnection.close();
});
dataChannel.onError(err => {
	console.log(`dataChannel.onError(): err: ${err}`);
});

4. In the Node REPL logs, copy the JSON stringified object after COPY LAST ONE PRINTED AS THE FINAL OFFER: . This is the final offer.

5. Paste the final offer into the offer variable below and run this snippet in the same Chrome DevTools Console:

const offer = ; // <--- Paste final offer here
await peerConnection.setRemoteDescription(offer);

const answer = await peerConnection.createAnswer();
await peerConnection.setLocalDescription(answer);

6. In the Chrome DevTools Console logs, copy the JSON stringified object after COPY LAST ONE PRINTED AS THE FINAL ANSWER: . This is the final answer.

7. Paste the final answer into the answer variable below and run this snippet in the same Node REPL:

const answer = ; // <--- Paste final answer here
const { sdp, type } = answer;
peerConnection.setRemoteDescription(sdp, type);

8. In the Node REPL logs, there's a probability of the following crash occuring:

FATAL ERROR: Error::New napi_get_last_error_info
 1: 0xb7a940 node::Abort() [node]
 2: 0xa8e72f node::FatalError(char const*, char const*) [node]
 3: 0xa8e738 node::OOMErrorHandler(char const*, bool) [node]
 4: 0xb40ac3 napi_fatal_error [node]
 5: 0x7fbd2ce055f0 Napi::CallbackScope::~CallbackScope() [<REPO_PATH>/node_modules/node-datachannel/build/Release/node_datachannel.node]
 6: 0x7fbd2ce05918 Napi::Error::New(napi_env__*) [<REPO_PATH>/node_modules/node-datachannel/build/Release/node_datachannel.node]
 7: 0x7fbd2cdeb5d3  [<REPO_PATH>/node_modules/node-datachannel/build/Release/node_datachannel.node]
 8: 0x7fbd2ce41255 ThreadSafeCallback::callbackFunc(Napi::Env, Napi::Function, Napi::Reference<Napi::Value>*, ThreadSafeCallback::CallbackData*) [<REPO_PATH>/node_modules/node-datachannel/build/Release/node_datachannel.node]
 9: 0xb4083c  [node]
10: 0x165f601 uv_run [node]
11: 0xabda6d node::SpinEventLoop(node::Environment*) [node]
12: 0xbc1164 node::NodeMainInstance::Run() [node]
13: 0xb35bc8 node::LoadSnapshotDataAndRun(node::SnapshotData const**, node::InitializationResult const*) [node]
14: 0xb3976f node::Start(int, char**) [node]
15: 0x7fbd34d00d0a __libc_start_main [/lib/x86_64-linux-gnu/libc.so.6]
16: 0xabbdee _start [node]
Aborted (core dumped)

crash-repro's People

Contributors

regnaio avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.