From: | Christian Kruse <christian(at)2ndQuadrant(dot)com> |
---|---|
To: | "pgsql-hackers(at)postgresql(dot)org" <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: Suspicion of a compiler bug in clang: using ternary operator in ereport() |
Date: | 2014-01-28 21:12:01 |
Message-ID: | 20140128211201.GD31380@defunct.ch |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
Hi,
On 28/01/14 16:43, Christian Kruse wrote:
> ereport(FATAL,
> (errmsg("could not map anonymous shared memory: %m"),
> (errno == ENOMEM) ?
> errhint("This error usually means that PostgreSQL's request "
> "for a shared memory segment exceeded available memory "
> "or swap space. To reduce the request size (currently "
> "%zu bytes), reduce PostgreSQL's shared memory usage, "
> "perhaps by reducing shared_buffers or "
> "max_connections.",
> *size) : 0));
>
> did not emit a errhint when using clang, although errno == ENOMEM was
> true. The same code works with gcc.
According to http://llvm.org/bugs/show_bug.cgi?id=18644#c5 this is not
a compiler bug but a difference between gcc and clang. Clang seems to
use a left-to-right order of evaluation while gcc uses a right-to-left
order of evaluation. So if errmsg changes errno this would lead to
errno == ENOMEM evaluated to false. I added a watch point on errno and
it turns out that exactly this happens: in src/common/psprintf.c line
114
nprinted = vsnprintf(buf, len, fmt, args);
errno gets set to 0. This means that we will miss errhint/errdetail if
we use errno in a ternary operator and clang.
Should we work on this issue?
Best regards,
--
Christian Kruse http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
From | Date | Subject | |
---|---|---|---|
Next Message | Alvaro Herrera | 2014-01-28 21:19:11 | Re: Patch: regexp_matches variant returning an array of matching positions |
Previous Message | Bruce Momjian | 2014-01-28 21:11:54 | Re: fixing pg_ctl with relative paths |