PCRE2Project / pcre2

PCRE2 development is now based here.
Other
883 stars 185 forks source link

Matching a 32 MB binary with mostly NULs freezes on arm64 with JIT #257

Closed tempelmann closed 1 year ago

tempelmann commented 1 year ago

I have a sample file (attached) then, when searching for a string in the file, the match function won't return if JIT is enabled and if it's on an ARM (Apple Silicon) machine. Without JIT, or on Intel arch, the problem does not occur.

I have reproduced this issue with both 10.42 and the current master (as of May 30, 2023).

I'm attaching the source code for testing and the zipped sample file (unpack it and move "HFS4_small.dmg" into the same folder where to the built test program lies). I also attach the built test program (built for ARM and x64 for macOS).

To reproduce: Run the pcre2demo program. On an Intel Mac, it should print "finished". On an ARM, it'll not finish, at least not within the < 1 second it takes on Intel, nor within a minute.

pcre2demo.zip HFS4_small.dmg.zip pcre2demo.c.zip

zherczeg commented 1 year ago

Would it be possible to run your code with gdb, stop after a second, and get a backtrace?

tempelmann commented 1 year ago

Zoltan, can you give me detailed instructions on which commands I need to use? Especially, how do I break into gdb after the code hangs?

zherczeg commented 1 year ago

run your binary with gdb: gdb --args prog_name prog_args... type r (short form of run) wait 1 sec ctrl+c to stop execution type bt (short form of backtrace) copy the output here

tempelmann commented 1 year ago

Nevermind what I wrote before. Turns out that there's a difference between lldb ./pcre2demo and lldb pcre2demo.

tempelmann commented 1 year ago
% lldb pcre2demo 
(lldb) target create "pcre2demo"
Current executable set to '/Users/tt/Desktop/pcre2demo' (arm64).
(lldb) r
Process 14298 launched: '/Users/tt/Desktop/pcre2demo' (arm64)
Process 14298 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
    frame #0: 0x000000010003e1a8 pcre2demo`ffcs_mask + 148
pcre2demo`ffcs_mask:
->  0x10003e1a8 <+148>: fmov   x9, d2
    0x10003e1ac <+152>: cbnz   x9, 0x10003e1e0           ; <+204>
    0x10003e1b0 <+156>: mov.d  x9, v2[1]
    0x10003e1b4 <+160>: add    x8, x8, #0x10
Target 0: (pcre2demo) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
  * frame #0: 0x000000010003e1a8 pcre2demo`ffcs_mask + 148
    frame #1: 0x00000001021470ec
    frame #2: 0x0000000100027254 pcre2demo`jit_machine_stack_exec + 80
    frame #3: 0x00000001000271b0 pcre2demo`pcre2_jit_match_8 + 268
    frame #4: 0x000000010005cff4 pcre2demo`pcre2_match_8 + 504
    frame #5: 0x0000000100004650 pcre2demo`main + 192
    frame #6: 0x00000001a08e7f28 dyld`start + 2236
(lldb) c
Process 14298 resuming
Process 14298 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
    frame #0: 0x000000010003e1a8 pcre2demo`ffcs_mask + 148
pcre2demo`ffcs_mask:
->  0x10003e1a8 <+148>: fmov   x9, d2
    0x10003e1ac <+152>: cbnz   x9, 0x10003e1e0           ; <+204>
    0x10003e1b0 <+156>: mov.d  x9, v2[1]
    0x10003e1b4 <+160>: add    x8, x8, #0x10
Target 0: (pcre2demo) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
  * frame #0: 0x000000010003e1a8 pcre2demo`ffcs_mask + 148
    frame #1: 0x00000001021470ec
    frame #2: 0x0000000100027254 pcre2demo`jit_machine_stack_exec + 80
    frame #3: 0x00000001000271b0 pcre2demo`pcre2_jit_match_8 + 268
    frame #4: 0x000000010005cff4 pcre2demo`pcre2_match_8 + 504
    frame #5: 0x0000000100004650 pcre2demo`main + 192
    frame #6: 0x00000001a08e7f28 dyld`start + 2236
(lldb) 
zherczeg commented 1 year ago

Thank you. This is the simd helper for the fast character search in arm. @carenas I think you have access to apple systems, and we have already fixed issues with this helper before.

carenas commented 1 year ago

FWIW, it also affects non apple aarch64 systems.

The problem might only trigger with partial matches, which the helper might had never intended to support, but only @sebpop would know.

@tempelmann: as a workaround could you do non partial matches?, AFAIK partial matches were meant to be used mostly as aids for interactive tools that provide autocompletion through regex, which does not seem to be the case here.