On Fri, 24 Dec 2021 21:40:24 -0800 (PST)
Jeremy Drake wrote:
> On Sat, 25 Dec 2021, Takashi Yano wrote:
> 
> > On Fri, 24 Dec 2021 19:47:46 -0800 (PST)
> > Jeremy Drake wrote:
> > > phi->NumberOfHandles = 7999168, n_handle = 256
> > > assertion "phi->NumberOfHandles <= n_handle" failed: file
> > > "../../.././winsup/cygwin/fhandler_pipe.cc", line 1280, function: void*
> > > fhandler_pipe::get_query_hdl_per_process(WCHAR*, OBJECT_NAME_INFORMATION*)
> > > Aborted
> >
> > What!? Could you please check value of the "status" ?
> 
> status = 0x00000000, phi->NumberOfHandles = 7286688, n_handle = 256
> assertion "phi->NumberOfHandles <= n_handle" failed: file
> "../../.././winsup/cygwin/fhandler_pipe.cc", line 1281, function: void*
> fhandler_pipe::get_query_hdl_per_process(WCHAR*, OBJECT_NAME_INFORMATION*)
> Aborted
> 
> > What version of windows do you use?
> 
> This was on Windows 11 (22000.376) on ARM64, but msys2 has started seeing
> similar hangs on Github's "windows-2022" runner.  I don't have one of
> those locally to test against however.  But if push came to shove, I think
> I downloaded a Server 2022 evaluation ISO, I could set up a VM and see
> what happens.

Could you please check the result of the following test case
in that ARM64 platform?

The following code can be compiled using mingw compiper with
-lntdll flag.

#include <windows.h>
#include <ntdef.h>
#include <ntstatus.h>
#include <stdlib.h>
#include <stdio.h>

typedef enum
{
  ProcessHandleInformation = 51 /* Since Win8 */
} PROCESSINFOCLASS;

typedef struct
{
  HANDLE HandleValue;
  ULONG_PTR HandleCount;
  ULONG_PTR PointerCount;
  ULONG GrantedAccess;
  ULONG ObjectTypeIndex;
  ULONG HandleAttributes;
  ULONG Reserved;
} PROCESS_HANDLE_TABLE_ENTRY_INFO, *PPROCESS_HANDLE_TABLE_ENTRY_INFO;

typedef struct
{
  ULONG_PTR NumberOfHandles;
  ULONG_PTR Reserved;
  PROCESS_HANDLE_TABLE_ENTRY_INFO Handles[1];
} PROCESS_HANDLE_SNAPSHOT_INFORMATION;


NTSTATUS NTAPI NtQueryInformationProcess (HANDLE, PROCESSINFOCLASS,
  PVOID, ULONG, PULONG);

typedef enum
{
  SystemHandleInformation = 16
} SYSTEM_INFORMATION_CLASS;

typedef struct
{
  USHORT UniqueProcessId;
  USHORT CreatorBackTraceIndex;
  UCHAR ObjectTypeIndex;
  UCHAR HandleAttributes;
  USHORT HandleValue;
  PVOID Object;
  ULONG GrantedAccess;
} SYSTEM_HANDLE_TABLE_ENTRY_INFO;

typedef struct
{
  ULONG NumberOfHandles;
  SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1];
} SYSTEM_HANDLE_INFORMATION;

NTSTATUS NTAPI NtQuerySystemInformation (SYSTEM_INFORMATION_CLASS,
  PVOID, ULONG, PULONG);

int main()
{
        NTSTATUS status;
        DWORD n_handle = 1;
        PROCESS_HANDLE_SNAPSHOT_INFORMATION *phi;
        do {
                DWORD nbytes = 2 * sizeof(ULONG_PTR)
                        + n_handle * sizeof(PROCESS_HANDLE_TABLE_ENTRY_INFO);
                phi = (PROCESS_HANDLE_SNAPSHOT_INFORMATION *)
                        HeapAlloc(GetProcessHeap(), 0, nbytes);
                if (!phi) {
                        fprintf(stderr, "HeapAlloc() Error: %08x\n", 
GetLastError());
                        exit(1);
                }
                ULONG len;
                status = NtQueryInformationProcess(GetCurrentProcess(),
                        ProcessHandleInformation, phi, nbytes, &len);
                if (NT_SUCCESS (status)) break;
                HeapFree(GetProcessHeap(), 0, phi);
                n_handle ++;
        } while (status == STATUS_INFO_LENGTH_MISMATCH);

        if (!NT_SUCCESS (status)) {
                fprintf(stderr, "NtQueryInformationProcess() error: %08x\n", 
status);
                HeapFree(GetProcessHeap(), 0, phi);
                exit(1);
        }

        printf("per_process: n_handle=%d, NumberOfHandles=%d\n",
                n_handle, phi->NumberOfHandles);
        if (phi->NumberOfHandles > n_handle) {
                HeapFree(GetProcessHeap(), 0, phi);
                exit(1);
        }
        HeapFree(GetProcessHeap(), 0, phi);


        n_handle = 1;
        SYSTEM_HANDLE_INFORMATION *shi;
        do {
                SIZE_T nbytes = sizeof(ULONG)
                        + n_handle * sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO);
                shi = (SYSTEM_HANDLE_INFORMATION *) HeapAlloc (GetProcessHeap(),
                        0, nbytes);
                if (!shi) {
                        fprintf(stderr, "HeapAlloc() Error: %08x\n", 
GetLastError());
                        exit(1);
                }
                status = NtQuerySystemInformation(SystemHandleInformation,
                        shi, nbytes, NULL);
                if (NT_SUCCESS(status)) break;
                HeapFree (GetProcessHeap(), 0, shi);
                n_handle *= 2;
        } while (status == STATUS_INFO_LENGTH_MISMATCH);
        
        if (!NT_SUCCESS (status)) {
                fprintf(stderr, "NtQuerySystemInformation() error: %08x\n", 
status);
                HeapFree(GetProcessHeap(), 0, shi);
                exit(1);
        }

        printf("per_system: n_handle=%d, NumberOfHandles=%d\n",
                n_handle, shi->NumberOfHandles);
        if (shi->NumberOfHandles > n_handle) {
                HeapFree(GetProcessHeap(), 0, shi);
                exit(1);
        }
        HeapFree(GetProcessHeap(), 0, shi);

        return 0;
}

-- 
Takashi Yano <takashi.y...@nifty.ne.jp>

Reply via email to