Re: maximum number of backtrace frames logged by backtrace_functions

From: Fujii Masao <masao(dot)fujii(at)oss(dot)nttdata(dot)com>
To: Peter Eisentraut <peter(dot)eisentraut(at)enterprisedb(dot)com>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: pgsql-docs(at)lists(dot)postgresql(dot)org
Subject: Re: maximum number of backtrace frames logged by backtrace_functions
Date: 2022-02-18 16:05:04
Message-ID: 070467b6-1ead-8921-89a1-5ec39d1f2103@oss.nttdata.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-docs

On 2022/02/18 19:59, Peter Eisentraut wrote:
> On 18.02.22 09:24, Fujii Masao wrote:
>> Or even backtrace should be logged by write_stderr() so that it's written to eventlog if necessary? I just wonder why backtrace_symbols_fd() is used only in ExceptionalCondition().
>
> Probably because it was simpler.  It would also make sense to convert the whole thing to use write_stderr() consistently.
+1
Attached is the updated version of the patch that uses write_stderr() to log the backtrace in assertion failure case.

+ if (nframes >= lengthof(buf))
+ appendStringInfo(&errtrace, "\n(backtrace limited to %zu frames)",
+ lengthof(buf));

I found this doesn't work on FreeBSD, at least FreeBSD 13 that cfbot uses on Cirrus CI. When the backtrace is larger than 100, on FreeBSD, backtrace() seems to write the *99* (not 100) most recent function calls to the buffer. That is, the variable "nframes" is 99 while lengthof(buf) indicates 100. So the above message about backtrace limit will never be logged on FreeBSD. OTOH, on Linux and MacOS, backtrace() writes the 100 most recent function calls. I'm not sure if such a behavior on FreeBSD is expected or a bug.

To issue the message whatever OS is, probably we need to modify set_backtrace() as follows, for example. But is this overkill? Thought?

- void *buf[100];
+#define BACKTRACE_MAX_FRAMES 100
+ void *buf[BACKTRACE_MAX_FRAMES + 1];
int nframes;
char **strfrms;

nframes = backtrace(buf, lengthof(buf));
+ if (nframes > BACKTRACE_MAX_FRAMES)
+ nframes = BACKTRACE_MAX_FRAMES;
strfrms = backtrace_symbols(buf, nframes);
if (strfrms == NULL)
return;

for (int i = num_skip; i < nframes; i++)
appendStringInfo(&errtrace, "\n%s", strfrms[i]);
+ if (nframes >= BACKTRACE_MAX_FRAMES)
+ appendStringInfo(&errtrace, "\n(backtrace limited to %d frames)",
+ BACKTRACE_MAX_FRAMES);

Regards,

--
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION

Attachment Content-Type Size
backtrace_limit_report_v3.patch text/plain 1.7 KB

In response to

Responses

Browse pgsql-docs by date

  From Date Subject
Next Message Daniel Westermann (DWE) 2022-02-26 16:54:24 hot standby <-> Hot Standby
Previous Message David G. Johnston 2022-02-18 14:51:12 Re: Copy Documentation