Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Firefox hangs when searching with / and a text input field is open, only when there's a match #206

Open
afarah1 opened this issue Apr 6, 2017 · 6 comments

Comments

@afarah1
Copy link

afarah1 commented Apr 6, 2017

Whenever I search with / and I have a page open which contains a text input field and there is a match, Firefox hangs. This did not happen on previous versions of Firefox, and doesn't happen without Pentadactyl (i.e. when searching with Ctrl+F). I'm using Mozilla Firefox 45.8.0 from Gentoo and Pentadactyl hg7290. I'm not sure how to provide more debug info since Firefox completely hangs when this happens. I provide the last 50 lines of an strace below. My session consisted of opening this page, writing "if" in the text field, and then searching for "if" with /. Firefox then hangs and I send SIGTERM to it. If the entire strace would be useful I can provide it (are there no privacy issues in doing so?).

futex(0x7f49d5c00040, FUTEX_WAIT_PRIVATE, 2, NULL) = -1 EAGAIN (Resource temporarily unavailable)
futex(0x7f49d5c00040, FUTEX_WAKE_PRIVATE, 1) = 0
futex(0x7f49d5bfda4c, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7f49d5bfda48, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
futex(0x7f49d5c00040, FUTEX_WAIT_PRIVATE, 2, NULL) = -1 EAGAIN (Resource temporarily unavailable)
futex(0x7f49d5c00040, FUTEX_WAKE_PRIVATE, 1) = 0
futex(0x7f49d5c00040, FUTEX_WAKE_PRIVATE, 1) = 0
futex(0x7f49d5bfda4c, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7f49d5bfda48, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
futex(0x7f49d5bfda4c, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7f49d5bfda48, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
futex(0x7f49d5c00040, FUTEX_WAIT_PRIVATE, 2, NULL) = -1 EAGAIN (Resource temporarily unavailable)
futex(0x7f49d5c00040, FUTEX_WAKE_PRIVATE, 1) = 0
futex(0x7f49d5c00040, FUTEX_WAIT_PRIVATE, 2, NULL) = -1 EAGAIN (Resource temporarily unavailable)
futex(0x7f49d5c00040, FUTEX_WAKE_PRIVATE, 1) = 0
futex(0x7f49d5c00040, FUTEX_WAIT_PRIVATE, 2, NULL) = -1 EAGAIN (Resource temporarily unavailable)
futex(0x7f49d5c00040, FUTEX_WAKE_PRIVATE, 1) = 0
futex(0x7f49d5bfda4c, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7f49d5bfda48, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
futex(0x7f49d5bfda4c, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7f49d5bfda48, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
futex(0x7f49d5bfda4c, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7f49d5bfda48, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
futex(0x7f49d5bfda4c, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7f49d5bfda48, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
futex(0x7f49d5c00040, FUTEX_WAIT_PRIVATE, 2, NULL) = -1 EAGAIN (Resource temporarily unavailable)
futex(0x7f49d5c00040, FUTEX_WAKE_PRIVATE, 1) = 0
futex(0x7f49d5bfda4c, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7f49d5bfda48, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
futex(0x7f49d5c00040, FUTEX_WAIT_PRIVATE, 2, NULL) = -1 EAGAIN (Resource temporarily unavailable)
futex(0x7f49d5c00040, FUTEX_WAKE_PRIVATE, 1) = 0
mmap(0x249d7b11a000, 65536, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x249d7b11a000
futex(0x7f49d5c00040, FUTEX_WAIT_PRIVATE, 2, NULL) = -1 EAGAIN (Resource temporarily unavailable)
futex(0x7f49d5c00040, FUTEX_WAKE_PRIVATE, 1) = 0
futex(0x7f49d5c00040, FUTEX_WAIT_PRIVATE, 2, NULL) = -1 EAGAIN (Resource temporarily unavailable)
futex(0x7f49d5c00040, FUTEX_WAKE_PRIVATE, 1) = 0
futex(0x7f49d5c00040, FUTEX_WAIT_PRIVATE, 2, NULL) = -1 EAGAIN (Resource temporarily unavailable)
futex(0x7f49d5c00040, FUTEX_WAKE_PRIVATE, 1) = 0
futex(0x7f49d5c00040, FUTEX_WAIT_PRIVATE, 2, NULL) = -1 EAGAIN (Resource temporarily unavailable)
futex(0x7f49d5c00040, FUTEX_WAKE_PRIVATE, 1) = 0
futex(0x7f49d5c00040, FUTEX_WAIT_PRIVATE, 2, NULL) = -1 EAGAIN (Resource temporarily unavailable)
futex(0x7f49d5c00040, FUTEX_WAKE_PRIVATE, 1) = 0
futex(0x7f49d5c00040, FUTEX_WAIT_PRIVATE, 2, NULL) = -1 EAGAIN (Resource temporarily unavailable)
futex(0x7f49d5c00040, FUTEX_WAKE_PRIVATE, 1) = 0
futex(0x7f49d5c00040, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x7f49d5bfda4c, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7f49d5bfda48, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
futex(0x7f49d5c00040, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x7f49d5c00040, FUTEX_WAIT_PRIVATE, 2, NULL) = -1 EAGAIN (Resource temporarily unavailable)
futex(0x7f49d5c00040, FUTEX_WAKE_PRIVATE, 1) = 0
futex(0x7f49d5c00040, FUTEX_WAKE_PRIVATE, 1) = 0
--- SIGTERM {si_signo=SIGTERM, si_code=SI_USER, si_pid=4565, si_uid=0} ---
unlink("/home/ff/.mozilla/firefox/32lkn570.default/lock") = 0
close(7)                                = 0
rt_sigaction(SIGTERM, {SIG_DFL, [], SA_RESTORER, 0x7f49d6d62ec0}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [TERM], NULL, 8) = 0
tgkill(1920, 1920, SIGTERM)             = 0
--- SIGTERM {si_signo=SIGTERM, si_code=SI_TKILL, si_pid=1920, si_uid=1001} ---
+++ killed by SIGTERM +++
@afarah1
Copy link
Author

afarah1 commented Jun 18, 2017

Okay, I was able to pinpoint the issue. It's an infinite loop in common/modules/finder.jsm:491. That is, in the highlight function of the RangeFind class. Link. When removing that loop the issue disappears entirely (though highlighting results also breaks).

I got to this by placing a breakpoint before and after the loop (after trying other spots at finder.jsm). It reaches the first breakpoint, I press play, but it never reaches the second - Firefox becomes irresponsible and I have to kill it.

I am testing it on a more recent version of Firefox than I previously reported:

:version
Pentadactyl 1.2pre (created 2017/05/31 22:07:30) running on:
Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0

Can any devs take a look at this?

@Massimo-B
Copy link

Any news here, if this can be fixed?

@troyp
Copy link

troyp commented Jan 16, 2018

One simple way to work around this is to hide the input elements while the highlighting is done and restore them. I tested it (manually) and it works. (Obviously, the matches in the input fields are left out.)

If you restore the fields immediately after the highlighting, you do lose the wraparound behaviour of n/N however: to get back to the top match from the bottom, you have to reverse direction or repeat the search. If you leave the fields hidden, n/N wil work normally.

Note: once the fields are unhidden and the highlighting is cancelled, pressing n/N will freeze the browser, since it repeats the search highlighting with the input fields visible. (If you wanted, you could prevent this issue by never actually cancelling the search highlighting, but instead hiding it temporarily using a style.)

If you want to test it, you can use these commands from my .pentadactylrc:

command! hideselector  -nargs=* -js hideSelectors.call(null, ...args);
command! unhideselector  -nargs=* -js unhideSelectors.call(null, ...args);

js <<EOF
function hideSelectors(...sels) {
    var doc = content.document;
    sels.forEach(sel=>{
        var elts = Array.from(doc.querySelectorAll(sel));
        elts.forEach(e=>{
            var css = e.getAttribute('style') || '';
            e.setAttribute('style', css+" display: none !important;");
        });
    });
}
function unhideSelectors(...sels) {
    var doc = content.document;
    sels.forEach(sel=>{
        var elts = Array.from(doc.querySelectorAll(sel));
        elts.forEach(e=>{
            var css = e.getAttribute('style') || '';
            var hideregex = /(^|;| ) *display: *none *(!important)? *;/g;
            e.setAttribute('style', css.replace(hideregex, ''));
        });
    });
}
EOF

I tried rebinding /, n and N to hide the input fields first, and using C-/ to clear the highlighting and unhide the input fields.

map <hide-inputs> -ex hideselector input
map <unhide-inputs> -ex unhideselector input
map / <hide-inputs><find-forward>
map n <hide-inputs><find-next>
map N <hide-inputs><find-previous>
map <C-/> -ex noh | unhideselector input

but it seemed a bit unreliable, so I've settled on just rebinding / and leaving the input fields hidden. If I need them again after searching, I have a binding specifically to restore them:

map <hide-inputs> -ex hideselector input
map <unhide-inputs> -ex unhideselector input
map / <hide-inputs><find-forward>
map <C-?> <unhide-inputs>

This can be implemented in a .pentadactylrc file. A better workaround would be to hack the source so the highlight function simply ignores matches in input fields. I haven't tried that yet, but it sounds simple enough.

troyp added a commit to troyp/.pentadactyl that referenced this issue Jan 16, 2018
See issues:
* 5digits/dactyl#206 (comment)
* madand/pentadactyl-pm#2

The `RangeFinder.highlight()` function from `finder.jsm` gets stuck in an
infinite loop when the search term matches input field text.

Rebind `/` and `?` to first hide all input fields, then search. In case the
input fields are required again, `<C-?>` unhides them.
@Massimo-B
Copy link

As this issue is annoying I'm going to test your workaround. However I would appreciate a bugfix in the sources.

@Massimo-B
Copy link

This seems to work sometimes, but now always.
For instance: Search an IP address if some edit field is open.

How to reproduce:

..freezing.

@Massimo-B
Copy link

This is still unstable, last freeze on https://forums.gentoo.org, writing a comment, preview, search by /, freeze. Which is most annoying as all the comment is lost...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants