format_datum debugging function

Started by Paul Jungwirthover 1 year ago8 messageshackers
Jump to latest
#1Paul Jungwirth
pj@illuminatedcomputing.com

Hi Hackers,

Often in a debugger I've wanted to way to print Datums, in particular non-trivial ones like range
types. This came up a lot when I was working on multiranges, and I've wished for it lately while
working on UPDATE/DELETE FOR PORTION OF. But all the obvious approaches are inlined functions or
preprocessor macros, so they aren't available. Usually I wind up giving up on gdb and adding elog
statements. Once or twice I've copy/pasted from the three or four levels of nested macros to make
gdb do what I wanted, but it's a pain.

I assumed printing a Datum was easy, and I was the only one who didn't know how to do it. But
perhaps not. The conversation about print.c [1]/messages/by-id/7d023c20-6679-44bd-b5f7-44106659bd5a@eisentraut.org made me think I should propose a way to make it
easier. This function takes a Datum and the appropriate out function, and returns a char *. So you
can do this:

(gdb) call format_datum(range_out, $1)
$2 = 0x59162692d938 "[1,4)"

I assume a patch like this doesn't need documentation. Does it need a test? Anything else?

[1]: /messages/by-id/7d023c20-6679-44bd-b5f7-44106659bd5a@eisentraut.org

Yours,

--
Paul ~{:-)
pj@illuminatedcomputing.com

#2Aleksander Alekseev
aleksander@timescale.com
In reply to: Paul Jungwirth (#1)
Re: format_datum debugging function

Hi Paul,

[...] This function takes a Datum and the appropriate out function, and returns a char *. So you
can do this:

(gdb) call format_datum(range_out, $1)
$2 = 0x59162692d938 "[1,4)"

I assume a patch like this doesn't need documentation. Does it need a test? Anything else?

I think you forgot to attach the patch. Or is it just a proposal?

--
Best regards,
Aleksander Alekseev

#3Paul Jungwirth
pj@illuminatedcomputing.com
In reply to: Aleksander Alekseev (#2)
Re: format_datum debugging function

On 8/12/24 04:32, Aleksander Alekseev wrote:

[...] This function takes a Datum and the appropriate out function, and returns a char *. So you
can do this:

(gdb) call format_datum(range_out, $1)
$2 = 0x59162692d938 "[1,4)"

I assume a patch like this doesn't need documentation. Does it need a test? Anything else?

I think you forgot to attach the patch. Or is it just a proposal?

Sorry, patch attached here.

Yours,

--
Paul ~{:-)
pj@illuminatedcomputing.com

Attachments:

v1-0001-Add-format_datum-debugging-function.patchtext/x-patch; charset=UTF-8; name=v1-0001-Add-format_datum-debugging-function.patchDownload+20-1
#4Jelte Fennema-Nio
postgres@jeltef.nl
In reply to: Paul Jungwirth (#3)
Re: format_datum debugging function

On Mon, 12 Aug 2024 at 23:15, Paul Jungwirth
<pj@illuminatedcomputing.com> wrote:

On 8/12/24 04:32, Aleksander Alekseev wrote:

(gdb) call format_datum(range_out, $1)
$2 = 0x59162692d938 "[1,4)"

I assume a patch like this doesn't need documentation. Does it need a test? Anything else?

I think you forgot to attach the patch. Or is it just a proposal?

Sorry, patch attached here.

+1 for the idea. And the code looks trivial enough. I think this
should also contain a print_datum function too though.

#5Peter Eisentraut
peter_e@gmx.net
In reply to: Paul Jungwirth (#3)
Re: format_datum debugging function

On 12.08.24 23:15, Paul Jungwirth wrote:

On 8/12/24 04:32, Aleksander Alekseev wrote:

[...] This function takes a Datum and the appropriate out function,
and returns a char *. So you
can do this:

(gdb) call format_datum(range_out, $1)
$2 = 0x59162692d938 "[1,4)"

I assume a patch like this doesn't need documentation. Does it need a
test? Anything else?

I think you forgot to attach the patch. Or is it just a proposal?

Sorry, patch attached here.

I don't think it's safe to call output functions at arbitrary points
from a debugger. But if you're okay with that during development, say,
then I think you could just call OidOutputFunctionCall(F_RANGE_OUT, $1)?

#6Paul Jungwirth
pj@illuminatedcomputing.com
In reply to: Peter Eisentraut (#5)
Re: format_datum debugging function

On 8/14/24 02:16, Peter Eisentraut wrote:

On 12.08.24 23:15, Paul Jungwirth wrote:

On 8/12/24 04:32, Aleksander Alekseev wrote:

[...] This function takes a Datum and the appropriate out function, and returns a char *. So you
can do this:

(gdb) call format_datum(range_out, $1)
$2 = 0x59162692d938 "[1,4)"

I assume a patch like this doesn't need documentation. Does it need a test? Anything else?

I think you forgot to attach the patch. Or is it just a proposal?

Sorry, patch attached here.

I don't think it's safe to call output functions at arbitrary points from a debugger.  But if you're
okay with that during development, say, then I think you could just call
OidOutputFunctionCall(F_RANGE_OUT, $1)?

I assumed it wasn't safe everywhere (e.g. there is potentially a TOAST lookup), but for debugging a
patch that's okay with me.

Are you doing something to get macro expansion? I've never gotten my gdb to see #defines, although
in theory this configure line should do it, right?:

./configure 'CFLAGS=-ggdb -Og -g3 -fno-omit-frame-pointer' --enable-tap-tests --enable-cassert
--enable-debug --prefix=${HOME}/local

I also tried -gdwarf and -gdwarf-4 and -gdwarf-5 (all still with -Og -g3).

If it makes a difference, I'm attaching to a process:

paul@tal:~/src/postgresql$ gdb -p 1175735
GNU gdb (Ubuntu 12.1-0ubuntu1~22.04.2) 12.1
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html&gt;
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/&gt;.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/&gt;.

For help, type "help".
Type "apropos word" to search for commands related to "word".
Attaching to process 1175735
Reading symbols from /home/paul/local/bin/postgres...
Reading symbols from /lib/x86_64-linux-gnu/libz.so.1...
(No debugging symbols found in /lib/x86_64-linux-gnu/libz.so.1)
Reading symbols from /lib/x86_64-linux-gnu/libm.so.6...
Reading symbols from /usr/lib/debug/.build-id/a5/08ec5d8bf12fb7fd08204e0f87518e5cd0b102.debug...
Reading symbols from /lib/x86_64-linux-gnu/libicui18n.so.70...
(No debugging symbols found in /lib/x86_64-linux-gnu/libicui18n.so.70)
Reading symbols from /lib/x86_64-linux-gnu/libicuuc.so.70...
(No debugging symbols found in /lib/x86_64-linux-gnu/libicuuc.so.70)
Reading symbols from /lib/x86_64-linux-gnu/libc.so.6...
Reading symbols from /usr/lib/debug/.build-id/49/0fef8403240c91833978d494d39e537409b92e.debug...
Reading symbols from /lib64/ld-linux-x86-64.so.2...
Reading symbols from /usr/lib/debug/.build-id/41/86944c50f8a32b47d74931e3f512b811813b64.debug...
Reading symbols from /lib/x86_64-linux-gnu/libstdc++.so.6...
(No debugging symbols found in /lib/x86_64-linux-gnu/libstdc++.so.6)
Reading symbols from /lib/x86_64-linux-gnu/libgcc_s.so.1...
(No debugging symbols found in /lib/x86_64-linux-gnu/libgcc_s.so.1)
Reading symbols from /lib/x86_64-linux-gnu/libicudata.so.70...
(No debugging symbols found in /lib/x86_64-linux-gnu/libicudata.so.70)
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
0x000079878e325dea in epoll_wait (epfd=7, events=0x573f0e475820, maxevents=1, timeout=-1) at
../sysdeps/unix/sysv/linux/epoll_wait.c:30
30 ../sysdeps/unix/sysv/linux/epoll_wait.c: No such file or directory.
(gdb) b range_in
Breakpoint 1 at 0x573f0d9b5042: file rangetypes.c, line 91.
(gdb) c
Continuing.

Breakpoint 1, range_in (fcinfo=0x7fff6d8fea90) at rangetypes.c:91
91 {
(gdb) fin
Run till exit from #0 range_in (fcinfo=0x7fff6d8fea90) at rangetypes.c:91
0x0000573f0da8c87e in InputFunctionCall (flinfo=0x7fff6d8feb20, str=0x573f0e47a258 "[3,5)",
typioparam=3904, typmod=-1) at fmgr.c:1547
1547 result = FunctionCallInvoke(fcinfo);
Value returned is $1 = 95928334988456
(gdb) call OidOutputFunctionCall(F_RANGE_OUT, $1)
No symbol "F_RANGE_OUT" in current context.

If I know the oid, then this works:

(gdb) call OidOutputFunctionCall(3835, $1)
$2 = 0x5f9be16ca4d8 "[3,5)"

That is a big improvement, but still a little annoying.

Thanks,

--
Paul ~{:-)
pj@illuminatedcomputing.com

#7Peter Eisentraut
peter_e@gmx.net
In reply to: Paul Jungwirth (#6)
Re: format_datum debugging function

On 14.08.24 17:46, Paul Jungwirth wrote:

On 8/14/24 02:16, Peter Eisentraut wrote:

On 12.08.24 23:15, Paul Jungwirth wrote:

On 8/12/24 04:32, Aleksander Alekseev wrote:

[...] This function takes a Datum and the appropriate out function,
and returns a char *. So you
can do this:

(gdb) call format_datum(range_out, $1)
$2 = 0x59162692d938 "[1,4)"

I assume a patch like this doesn't need documentation. Does it need
a test? Anything else?

I think you forgot to attach the patch. Or is it just a proposal?

Sorry, patch attached here.

I don't think it's safe to call output functions at arbitrary points
from a debugger.  But if you're okay with that during development,
say, then I think you could just call
OidOutputFunctionCall(F_RANGE_OUT, $1)?

I assumed it wasn't safe everywhere (e.g. there is potentially a TOAST
lookup), but for debugging a patch that's okay with me.

Are you doing something to get macro expansion? I've never gotten my gdb
to see #defines, although in theory this configure line should do it,
right?:

Oh I see, you don't have the F_* constants available then. Maybe just
put in the OID manually then?

#8Tom Lane
tgl@sss.pgh.pa.us
In reply to: Peter Eisentraut (#7)
Re: format_datum debugging function

Peter Eisentraut <peter@eisentraut.org> writes:

On 14.08.24 17:46, Paul Jungwirth wrote:

Are you doing something to get macro expansion? I've never gotten my gdb
to see #defines, although in theory this configure line should do it,
right?:

Oh I see, you don't have the F_* constants available then. Maybe just
put in the OID manually then?

That's pretty illegible and error-prone. I agree that writing the
output function's C name is noticeably better. However, I would
call the result DirectOutputFunctionCall and put it near
OidOutputFunctionCall in fmgr.c. It's not like we don't already
have a naming convention and many instances of this.

(Also, now that I look at the code, I wonder why it looks so
little like any of the existing DirectFunctionCall functions.)

regards, tom lane