-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Open
Labels
area-vmUse area-vm for VM related issues, including code coverage, and the AOT and JIT backends.Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends.library-io
Description
Self contained repro:
- It starts a TLS server, connects to it and sends 100Kb of data.
- The server accepts the connection, then does
socket.listen(...).pause()(which is equivalent to sleeping or doing work insideasync for (var pkt in socket) .... - This is enough to make the process consume 130% of CPU on my machine. (Process prints it itself, but it matches output from
top) - When paused in a debugger there's an isolate doing _secureHandshake again and again.
- If we send somewhat less data from the client, things work normally, I think the bug is how backpressure is applied when TLS buffers are full but OS buffers also have pending data.
- Similar code on non-secure Socket does not reproduce the bug.
- Splitting client and server into separate processes has the same issue (130% CPU is on the server process).
import 'dart:async';
import 'dart:io';
const port = 8443;
void main(List<String> args) async {
var ctx = SecurityContext()
..usePrivateKeyBytes(key_pem.codeUnits)
..useCertificateChainBytes(chain_pem.codeUnits);
var server = await SecureServerSocket.bind(InternetAddress.loopbackIPv4, port, ctx);
unawaited(Future.delayed(Duration(seconds: 3)).whenComplete(print_cpu_usage));
_main_client();
await _main_server(server);
}
Future<void> _main_server(SecureServerSocket server) async {
await for (var socket in server) {
print("[server] Client connected");
socket.listen((pkt) => print('[server] Received ${pkt.length} bytes')).pause();
}
}
void _main_client() async {
var socket = await SecureSocket.connect('localhost', port, onBadCertificate: (cert) => true);
print('[client] Connected to server');
socket.write('x' * 100_000);
await socket.flush();
await socket.close();
socket.destroy();
print('[client] done');
}
const chain_pem = '''
-----BEGIN CERTIFICATE-----
MIIBdjCCARugAwIBAgIUDzhDxwldDHzVPlRthjktkUO3wncwCgYIKoZIzj0EAwIw
EDEOMAwGA1UEAwwFZGVidWcwHhcNMjUxMTE5MTg0NTI0WhcNMjUxMTIwMTg0NTI0
WjAQMQ4wDAYDVQQDDAVkZWJ1ZzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABO1P
nxX0VpZOQjtPB4xEwxfERCcOjmfgMiYAzP7sZGI2xIPhZHyPi1UKNUKBphhRlkGN
wO2oOprvp2yeVsWNXWijUzBRMB0GA1UdDgQWBBSuVL6YvTycIDNiZAsDua9SccoL
XjAfBgNVHSMEGDAWgBSuVL6YvTycIDNiZAsDua9SccoLXjAPBgNVHRMBAf8EBTAD
AQH/MAoGCCqGSM49BAMCA0kAMEYCIQD+EhtD7czOf01y1HyjpDNPN6Aew/d9lFjb
dG/+1JGTaAIhALevCT6Q3gsk7vIX7qCKitnjgcp6fMjd5187vhyVRFqT
-----END CERTIFICATE-----
''';
const key_pem = '''
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEICisOLyuxuBM6hEluycCIZe19itEnBNKyt4Cy0etU+cAoAoGCCqGSM49
AwEHoUQDQgAE7U+fFfRWlk5CO08HjETDF8REJw6OZ+AyJgDM/uxkYjbEg+FkfI+L
VQo1QoGmGFGWQY3A7ag6mu+nbJ5WxY1daA==
-----END EC PRIVATE KEY-----
''';
Future<void> print_cpu_usage() async {
var hz = await _get_clk_tck();
var stat_raw = await File('/proc/self/stat').readAsString();
var uptime_raw = await File('/proc/uptime').readAsString();
var stat_after = stat_raw.substring(stat_raw.lastIndexOf(') ') + 2);
var parts = stat_after.split(' ');
// /proc/[pid]/stat fields (after ") "):
// 0: state (3), 1: ppid (4), ..., 11: utime (14), 12: stime (15), 19: starttime (22)
var utime = int.parse(parts[11]);
var stime = int.parse(parts[12]);
var starttime = int.parse(parts[19]);
var uptime_sec = double.parse(uptime_raw.split(' ').first);
var total_time_ticks = utime + stime;
var total_time_sec = total_time_ticks / hz;
var start_time_sec = starttime / hz;
var elapsed_sec = uptime_sec - start_time_sec;
var cpu_percent = elapsed_sec > 0 ? (total_time_sec / elapsed_sec) * 100.0 : 0.0;
stdout.writeln('CPU usage (avg since start): ${cpu_percent.toStringAsFixed(2)}%');
}
Future<double> _get_clk_tck() async {
try {
var result = await Process.run('getconf', ['CLK_TCK']);
if (result.exitCode == 0) {
return double.parse((result.stdout as String).trim());
}
} catch (_) {}
return 100.0; // common default on many Linux systems
}
Output:
[client] Connected to server
[server] Client connected
[client] done
CPU usage (avg since start): 130.12%
- Dart 3.10.0 (stable) (Thu Nov 6 05:24:55 2025 -0800) on "linux_x64"
- on linux / Linux 6.17.7-300.fc43.x86_64 #1 SMP PREEMPT_DYNAMIC Sun Nov 2 15:30:09 UTC 2025
- locale is en_US.UTF-8
Metadata
Metadata
Assignees
Labels
area-vmUse area-vm for VM related issues, including code coverage, and the AOT and JIT backends.Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends.library-io