Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1o6OtH-0001DQ-Ni for pgsql-hackers@arkaria.postgresql.org; Wed, 29 Jun 2022 04:01:23 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1o6OtF-0006km-1z for pgsql-hackers@arkaria.postgresql.org; Wed, 29 Jun 2022 04:01:21 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1o6OtE-0006kc-Nq for pgsql-hackers@lists.postgresql.org; Wed, 29 Jun 2022 04:01:20 +0000 Received: from mail-io1-xd31.google.com ([2607:f8b0:4864:20::d31]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1o6Ot4-0002Xu-7o for pgsql-hackers@lists.postgresql.org; Wed, 29 Jun 2022 04:01:19 +0000 Received: by mail-io1-xd31.google.com with SMTP id m13so14896870ioj.0 for ; Tue, 28 Jun 2022 21:01:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=byUvb3P8ixBhv9HEt72Je4Hia/sA0e8vG5/SZupeT50=; b=S/rV5xykkgpKaFu4Lja7civ0+v9x/tIXhnbtephiVSJHeowj6tL+i2+0LwZYcnmpLG 2+J1spxyMujc2xvrDlNAkINlAlHmzWWdgKS3iDfVoV6BBAuUJSMowzadWdUb98FRxFYq FT6FFHJiYcpQ34ANi7FfYbF5CKIT1SNhTGUZYHgFyLKeStPIoK0kQVpfpuztWfDYvjvj HoYxBu6JbSSpGiNpPPXhoLYqlBZwXbzfDgK+X5R9eW1AhfM4rdjZZzMzrqNLcx6jwv2o uXEC2ADWJ56iiDG5c5sfsSKhHZy4NYHCwl8/2lRdFaKU+NaSIzfw2TfdSWx45O9tU/3s is1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=byUvb3P8ixBhv9HEt72Je4Hia/sA0e8vG5/SZupeT50=; b=pboK4ztHUW3eKbukE/D7GFGJheXkLps7B3SJP7/gtRS2qElg7E2RdZ/OFaWnX7X/Kw /qj3JQoExFvDGaXMGmcSFvZXqjDhkrwMOwywFYD48V+x7WXqhlk2zoT9B9a772xbwIAF 2LFRC/lnNtpvRMZREkcJlVxzbqA0THVTsfFkVlGcKqmNO+CQRxu+Lw4mn1XvQ2uiMOEe Py85FiN9iEI1T91qx3zIXwuU/e3rVyTjk9jBxoVhyedgQ/9ORe1h9PsPB0Dp04aJB73E fAsKh1DaGrrcFP3L2xbZjdqOIRC8y3ipvIcRogPCyoJzPdydKBpl8NAo9CLdH1kUrDP1 Sd0Q== X-Gm-Message-State: AJIora94Anh/WCoTTg2IAaDY8yljFtLrp8LpHjsO6Dlg1CF+1SXv9Rhh 1BCsg0j+HAsQvuKQQ7b09QbhXra6+ZF8W6lkzxi+EUFChSVfVyYK X-Google-Smtp-Source: AGRyM1uFgcq/cWl6VHGjqBmL1Ks7Ax8xWs2gjBCjuJsX9mQU9Ub6qx/abeiqkJSK8oMNyB8GSzSHS2XoaF6srpI+hIU= X-Received: by 2002:a02:ccb3:0:b0:33c:946f:1294 with SMTP id t19-20020a02ccb3000000b0033c946f1294mr864226jap.29.1656475269182; Tue, 28 Jun 2022 21:01:09 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Thomas Munro Date: Wed, 29 Jun 2022 16:00:32 +1200 Message-ID: Subject: Re: margay fails assertion in stats/dsa/dsm code To: Robert Haas Cc: PostgreSQL Hackers , Marcel Hofstetter Content-Type: text/plain; charset="UTF-8" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Wed, Jun 29, 2022 at 6:04 AM Robert Haas wrote: > My first thought was that the return value of the call to > dsm_impl_op() at the end of dsm_attach() is not checked and that maybe > it was returning NULL, but it seems like whoever wrote > dsm_impl_posix() was pretty careful to ereport(elevel, ...) in every > failure path, and elevel is ERROR here, so I don't see any issue. My > second thought was that maybe control had escaped from dsm_attach() > due to an error before we got to the step where we actually map the > segment, but then the dsm_segment * would be returned to the caller. > Maybe they could retrieve it later using dsm_find_mapping(), but that > function has no callers in core. Thanks for looking. Yeah. I also read through that code many times and drew the same conclusion. > So I'm kind of stumped too, but did you by any chance check whether > there are any DSM-related messages in the logs before the assertion > failure? Marcel kindly granted me access to his test machine, where the failure can be reproduced by running make check lots of times. I eventually figured out that the problem control flow is ... of course ... the one path that doesn't ereport(), and that's when errno == EEXIST. That is a path that is intended to handle DSM_OP_CREATE. Here we are handling DSM_OP_ATTACH, and I have verified that we're passing in just O_RDWR. EEXIST is a nonsensical error for shm_open() without flags containing O_CREAT | O_EXCL (according to POSIX and Solaris's man page). On this OS, shm_open() opens plain files in /tmp (normally a RAM disk, so kinda like /dev/shm on Linux), that much I can tell with a plain old "ls" command. We can also read its long lost open source cousin (which may be completely different for all I know, but I'd doubt it): https://github.com/illumos/illumos-gate/blob/master/usr/src/lib/libc/port/rt/shm.c https://github.com/illumos/illumos-gate/blob/master/usr/src/lib/libc/port/rt/pos4obj.c Erm. It looks like __pos4obj_lock() could possibly return -1 and leave errno == EEXIST, if it runs out of retries? Then shm_open() would return -1, and we'd blow up. However, for that to happen, one of those "SHM_LOCK_TYPE" files would have to linger for 64 sleep loops, and I'm not sure why that'd happen, or what to do about it. (I don't immediately grok what that lock file is even for.) I suppose this could indicate that the machine and/or RAM disk is overloaded/swapping and one of those open() or unlink() calls is taking a really long time, and that could be fixed with some system tuning. I suppose it's also remotely possible that the process is getting peppered with signals so that funky shell script-style locking scheme is interrupted and doesn't really wait very long. Or maybe I guessed wrong and some other closed source path is to blame *shrug*. As for whether PostgreSQL needs to do anything, perhaps we should ereport for this unexpected error as a matter of self-preservation, to avoid the NULL dereference you'd presumably get on a non-cassert build with the current coding? Maybe just: - if (errno != EEXIST) + if (op == DSM_OP_ATTACH || errno != EEXIST) ereport(elevel, (errcode_for_dynamic_shared_memory(), errmsg("could not open shared memory segment \"%s\": %m", margay would probably still fail until that underlying problem is addressed, but less mysteriously on our side at least.