www.delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2025/02/24/19:52:36

DMARC-Filter: OpenDMARC Filter v1.4.2 delorie.com 51P0qYBP3848764
Authentication-Results: delorie.com; dmarc=pass (p=none dis=none) header.from=cygwin.com
Authentication-Results: delorie.com; spf=pass smtp.mailfrom=cygwin.com
DKIM-Filter: OpenDKIM Filter v2.11.0 delorie.com 51P0qYBP3848764
Authentication-Results: delorie.com;
dkim=pass (1024-bit key, unprotected) header.d=cygwin.com header.i=@cygwin.com header.a=rsa-sha256 header.s=default header.b=GSmNgeTx
X-Recipient: archive-cygwin AT delorie DOT com
DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8E01F3858CD9
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cygwin.com;
s=default; t=1740444752;
bh=QEjyWJfDnzYXlGm+uYS97WUuzklORQQ+akIWt5CckVE=;
h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post:
List-Help:List-Subscribe:From:Reply-To:From;
b=GSmNgeTxUWIj7tZlNXoZ5jaoG/qjW/4S8veLkzM2ZjsKPeoZuR+9zczuTVydisJvq
UqxmgGfJF0y5Jwl/FCQgj+R96Xt/MCuQedHELpULHFewaJIeFiqZkhHP+QtdrnXvTW
7l9+oj/jrcK1CvlEEksobCDUV67inDNKA6d2AKyk=
X-Original-To: cygwin AT cygwin DOT com
Delivered-To: cygwin AT cygwin DOT com
DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 060513858D33
ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 060513858D33
ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1740444717; cv=none;
b=HuxX+Hbx58UVa4frs/lRWByPsjLE2XMRJnTjYvjIFQ5YZMf7wccIn7nfrHEvEXdMAXn4uiuluP2DpbfSzX0extLvyL4DZfxrbLkxdIQEGvajkGOKPUsDtwjflzrY90QKcJvvUxELz76gIvI8SKyO1NaCnQlyhisdgR48NWUq0IA=
ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key;
t=1740444717; c=relaxed/simple;
bh=9iTO+ZFV4GEzP0+66d6p3yNIcsljozaMopfaUCW2+Bc=;
h=DKIM-Signature:Message-ID:Date:MIME-Version:To:From:Subject;
b=lyWPCE/TAo+d1ayYB+Xsggqx8pbx/mace7cbX4pJBRwLpTfX4RXuLbR5jOeFYUAfPeyfa1PhbEwEN4GN1xYOp6WZxEwFppB9IVqz/M5SwbBrIH9JsQkPkLShSvPdbOdb8T9I22AzfSNOzSa02DEcfp9R8BYWLIbMM4V/GkD9kqM=
ARC-Authentication-Results: i=1; server2.sourceware.org
DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 060513858D33
Message-ID: <fa85130b-9763-4b36-a431-1641667be253@anduin.net>
Date: Tue, 25 Feb 2025 01:51:52 +0100
MIME-Version: 1.0
User-Agent: Mozilla Thunderbird
To: cygwin AT cygwin DOT com
Subject: pipe.cc: Missing FILE_SYNCHRONOUS_IO_NONALERT in call to NtOpenFile
call in nt_create() - possibly leading to ENOSPC in UCRT
X-SA-Authenticated: Yes
X-BeenThere: cygwin AT cygwin DOT com
X-Mailman-Version: 2.1.30
List-Id: General Cygwin discussions and problem reports <cygwin.cygwin.com>
List-Archive: <https://cygwin.com/pipermail/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-request AT cygwin DOT com?subject=help>
List-Subscribe: <https://cygwin.com/mailman/listinfo/cygwin>,
<mailto:cygwin-request AT cygwin DOT com?subject=subscribe>
From: "knut st. osmundsen via Cygwin" <cygwin AT cygwin DOT com>
Reply-To: "knut st. osmundsen" <bird-cygwin AT anduin DOT net>
Sender: "Cygwin" <cygwin-bounces~archive-cygwin=delorie DOT com AT cygwin DOT com>
X-MIME-Autoconverted: from base64 to 8bit by delorie.com id 51P0qYBP3848764

Hi,

I've been hunting an issue for some days now, where a non-cygwin program 
using microsoft's UCRT sometimes end up with a sticky error on stdout 
when running under cygwin perl with a pipe capturing stdout and stderr.  
When the problem triggers, the pipe buffer appears to be full and it 
really looks like it's hitting the errno=ENOSPC/doserrno=0 situation at 
the tail end of _write_nolock() in ucrt/lowio/write.cpp.

I *think* the issue is that the write end of the pipe isn't configured 
to be synchronous.  In winsup/cygwin/fhandler/pipe.cc, the nt_create() 
function sets FILE_SYNCHRONOUS_IO_NONALERT when creating the _read_ end 
of the pipe using NtCreateNamedPipeFile, citing some C# program 
compatibility need.  But, the call to NtOpenFile below that opens the 
_write_ end of the pipe doesn't set it.  It does set the SYNCHRONIZE 
access right, but doesn't set the FILE_SYNCHRONOUS_IO_NONALERT flag 
(last parameter, is zero). This is akin to calling CreateFile with 
FILE_FLAG_OVERLAPPED, if I understand it correctly.


This lack of symmetry in the synchronization configuration between the 
two pipe ends looks like a bug to me, given the comment on read end 
saying "Set FILE_SYNCHRONOUS_IO_NONALERT flag so that native C# programs 
work with cygwin pipe".


I have found no way to enable the FILE_SYNCHRONOUS_IO_NONALERT behaviour 
on my end of the pipe after it has been created, unlike the ReadMode and 
CompletionMode (parameters 9 & 10 of the NtCreateNamedPipeFile call).  
The non-cygwin program in question has had issues with the 
FILE_PIPE_COMPLETE_OPERATION (PIPE_NOWAIT) and cygwin in the past, but 
that was solvable in a manner similar to calling 
fhandler_pipe::set_pipe_non_blocking(true). I can't come up with a good 
workaround for this problem, short of switching to a non-cygwin perl 
setup (painful).

The problem shows up sporadically (a few times almost every day lately) 
on an up-to-date windows server 2022 with a slightly dated cygwin setup 
(I doubt that matters much as the code in question seems to be unchanged 
in git head). It's a continuous build job that triggers this, and I'm 
not too keen on building my own cygwin dlls (haven't done that for at 
least 15 years) and placing them on this server.  I've tried to 
reproduce it locally on a similarly beefy Windows 11 workstation, but 
haven't had any luck at all, so either windows server 2022 specific 
kernel regression  or just your regular heisenbug.

The kernel code will do very different serialization for the pipe object 
when neither of the FILE_SYNCHRONOUS_IO_ALERT/NONALERT the flags are 
set, from what I can tell, though I haven't dug too deep into things 
yet. My guess, though, is it that if multiple threads/processes writes 
to an almost full pipe buffer at the same time, (Nt)WriteFile may 
sometimes return before writing the whole/any buffer, and thus upset 
the  stupid UCRT code.  Just forcing the pipe buffer to run full doesn't 
trigger it by it self, from what I can tell.


Also, in the error path of the NtOpenFile call, GetLastError() is used 
instead of __seterrno_from_nt_status() or RtlNtStatusToDosError().

Kind Regards,
  bird.

-- 
Problem reports:      https://cygwin.com/problems.html
FAQ:                  https://cygwin.com/faq/
Documentation:        https://cygwin.com/docs.html
Unsubscribe info:     https://cygwin.com/ml/#unsubscribe-simple

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019