jqlang / jq

Command-line JSON processor
https://jqlang.github.io/jq/
Other
29.59k stars 1.54k forks source link

1.7.1 dumps core on Cygwin, trying to find the input filename to print an error message #3129

Open Farmbuyer opened 1 month ago

Farmbuyer commented 1 month ago

The same bug as #1588 and #2116 is occurring again, but now with the 1.7 release.

The testcase from 2116 that was fixed at one point on master now breaks for me:

$ jq --version
jq-1.7.1

$ echo W3sKICAiY29kZV9ldmVudCI6ICIyMzU4NTYyfDI2NXwiLAogICJjb2RlX2V2ZW50X3N5c3RlbSI6ICJTVEFUSUMiLAogICJjb21wYW55X2lkIjogIjMiLAogICJkYXRlX2V2ZW50IjogIjIwMjAtMDMtMTQgMTc6MjA6MDAuMDAwIiwKICAiZGF0ZV9ldmVudF9yZWFsIjogIjAwMDEtMDEtMDEgMDA6MDA6MDAuMDAwIiwKICAiZWNvZGVfY2xhc3MiOiAiMjY1IiwKICAiZWNvZGVfZXZlbnQiOiAiNDgwNCIsCiAgImVwZXJpb2RfZXZlbnQiOiAiIiwKICAiZXRsX2RhdGUiOiAiMjAyMC0wNS0yNyIKfSx7CiAgImNvZGVfZXZlbnQiOiAiMjM1ODU2MnwyNjV8IiwKICAiY29kZV9ldmVudF9zeXN0ZW0iOiAiU1RBVElDIiwKICAiY29tcGFueV9pZCI6ICIzIiwKICAiZGF0ZV9ldmVudCI6ICIyMDIwLTAzLTE0IDE3OjIwOjAwLjAwMCIsCiAgImRhdGVfZXZlbnRfcmVhbCI6ICIwMDAxLTAxLTAxIDAwOjAwOjAwLjAwMCIsCiAgImVjb2RlX2NsYXNzIjogIjI2NSIsCiAgImVjb2RlX2V2ZW50IjogIjQ4MDQiLAogICJlcGVyaW9kX2V2ZW50IjogIiIsCiAgImV0bF9kYXRlIjogIjIwMjAtMDUtMjciCn0KXQ== | base64 -d | jq ".code_event"
assertion "cb == jq_util_input_next_input_cb" failed: file "/cygdrive/d/a/scallywag/jq/jq-1.7.1-1.x86_64/src/jq-1.7.1/src/util.c", line 360, function: jq_util_input_get_position
                      Aborted

The expected error there is supposed to be along the lines of jq: error (at <stdin>:21): Cannot index array with string "code_event".

The testcase from 1588 is simply

$ jq '.missing[]' <<<'{}'
assertion "cb == jq_util_input_next_input_cb" failed: file "/cygdrive/d/a/scallywag/jq/jq-1.7.1-1.x86_64/src/jq-1.7.1/src/util.c", line 360, function: jq_util_input_get_position
                      Aborted

I encountered the bug even when the input is from a regular file, not stdin:

$ jq '.[] | @tsv' amis.json
assertion "cb == jq_util_input_next_input_cb" failed: file "/cygdrive/d/a/scallywag/jq/jq-1.7.1-1.x86_64/src/jq-1.7.1/src/util.c", line 360, function: jq_util_input_get_position
                      Aborted

We're running Cygwin 3.5.3 on Windows 10 Enterprise 22H2, using jq-1.7.1 (the wacky "/cygdrive/d" source path in the assertion shows it was built under a cygwin environment rather than native windows).

Farmbuyer commented 1 month ago

I should add two notes: first, that the error still occurs when the JQ input commands/filters are themselves read from a file:

$ jq -f JQFILTER amis.json
assertion "cb == jq_util_input_next_input_cb" failed: file "/cygdrive/d/a/scallywag/jq/jq-1.7.1-1.x86_64/src/jq-1.7.1/src/util.c", line 360, function: jq_util_input_get_position
                      Aborted

And secondly, that the files here are all normal files on an NTFS filesystem, i.e., not one of Windows' "reparse points" used in implementing remote storage like OneDrive, Dropbox, Google Whateverit'scalledthisweek, and so on -- I know that some API calls can return unexpected results when what Windows presents is a file, ain't.

wader commented 1 month ago

Hmm strange. So is this any time a jq filter fails with an error? what about these two:

$ jq error <<< 123
jq: error (at <stdin>:1) (not a string): 123
$ jq -n error
jq: error (at <unknown>) (not a string): null
Farmbuyer commented 1 month ago

Yep, anything that causes an error situation; the error-printing routines themselves are what's calling the failing assert.

$ jq error <<< 123
assertion "cb == jq_util_input_next_input_cb" failed: file "/cygdrive/d/a/scallywag/jq/jq-1.7.1-1.x86_64/src/jq-1.7.1/src/util.c", line 360, function: jq_util_input_get_position
                                                                             Aborted

$ jq -n error
assertion "cb == jq_util_input_next_input_cb" failed: file "/cygdrive/d/a/scallywag/jq/jq-1.7.1-1.x86_64/src/jq-1.7.1/src/util.c", line 360, function: jq_util_input_get_position
                                                                             Aborted

(And yes, "Aborted" is indented stupidly far in the terminal, but that's a C library thing, not jq's responsibility.)

wader commented 1 month ago

Do you have gdb installed and are a familiar with it? then maybe you can do something like this:

$ gdb --args ./jq -n error
...
Reading symbols from ./jq...
(gdb) b jq_set_input_cb
Breakpoint 1 at 0x10578: file src/execute.c, line 1297.
(gdb) b jq_get_input_cb
Breakpoint 2 at 0x105ac: file src/execute.c, line 1302.
(gdb) r
Starting program: /Users/wader/src/jq/jq -n error
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/aarch64-linux-gnu/libthread_db.so.1".

Breakpoint 1, jq_set_input_cb (jq=0xaaaaaabad550, cb=0xaaaaaaac83a8 <jq_util_input_next_input_cb>, data=0xaaaaaabad7e0) at src/execute.c:1297
1297      jq->input_cb = cb;
(gdb) watch -location jq.input_cb
Hardware watchpoint 3: -location jq.input_cb
(gdb) c
Continuing.

Hardware watchpoint 3: -location jq.input_cb

Old value = (jv (*)(jq_state *, void *)) 0x0
New value = (jv (*)(jq_state *, void *)) 0xaaaaaaac83a8 <jq_util_input_next_input_cb>
jq_set_input_cb (jq=0xaaaaaabad550, cb=0xaaaaaaac83a8 <jq_util_input_next_input_cb>, data=0xaaaaaabad7e0) at src/execute.c:1298
1298      jq->input_cb_data = data;
(gdb) c
Continuing.

Breakpoint 2, jq_get_input_cb (jq=0xaaaaaabad550, cb=0xfffffffff980, data=0xfffffffff978) at src/execute.c:1302
1302      *cb = jq->input_cb;
(gdb) p jq.input_cb
$1 = (jq_input_cb) 0xaaaaaaac83a8 <jq_util_input_next_input_cb>
(gdb) c
Continuing.
jq: error (at <unknown>) (not a string): null
[Inferior 1 (process 15568) exited with code 05]
(gdb)

then maybe we can see when jq->input_cb changes or see what else fishy is going on

Farmbuyer commented 1 month ago

I have a slightly older copy of GDB installed, but never got it running under Cygwin. It's been a while and lots of changes have happened upstream, so I'll ask them what missing fixes I need to get GDB itself not crashing, and then try this again.

(The Cygwin maintainers for jq already release a version with debugging symbols present, so at least I don't have to duplicate their build environment to get that.)