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

MathJax hangs with 100% CPU when resource fails to load #1936

Closed
adamwulf opened this issue Feb 22, 2018 · 7 comments
Closed

MathJax hangs with 100% CPU when resource fails to load #1936

adamwulf opened this issue Feb 22, 2018 · 7 comments
Labels
Accepted Issue has been reproduced by MathJax team Fixed Test Available v2.7

Comments

@adamwulf
Copy link

MathJax hangs with 100% CPU if one if its files fails to load. My example uses mtable.js below, but I've seen this happen with other scripts failing to load as well.

I originally found this issue on 2.7.1, and was also able to reproduce the issue 100% of the time with the current master branch (commit 2965eab).

The test case can be found here: http://www.wikipediacorpus.com/Chapter1.html - Opening that URL will cause MathJax to hang in an infinite loop, and show the beachball cursor in Mac Safari until the browser kills the script.

The issue seems to occur when the browser fails to load a supporting resource file for some reason. In the example URL, i forced /MathJax/jax/output/HTML-CSS/autoload/mtable.js to 404 by renaming it to mtable2.js on the server. I'm purposefully causing the break here, but there's tons of reasons why a browser might fail to load a resource, which explains why #548 may have been so hard to reproduce.

When that file fails to load, the processOutput function circles in an infinite loop, continually trying to restart. I've added a console.log() to that method in the test URL above, which prints out the state.i value, and you can see in the JavaScript console that the value never increments above 7. The line that is throwing the restart error is line 2334:

        result = MathJax.OutputJax[jax.outputJax].Process(script,state);

As a workaround, the following seems to fix the issue:

         try{
                result = MathJax.OutputJax[jax.outputJax].Process(script,state);
         }catch(e){
            if(state.i == state.lastErr){
                state.i++;
                console.log("state.i: " + state.i);
            }else{
                state.lastErr = state.i;
                console.log("other: " + state.i);
            }
            throw e;
         }

Otherwise, that line throws a restart Error, having never incremented state.i, and the whole process repeats itself.

I ran into this issue while working on MacDown, a native markdown client for Mac, which uses MathJax in its preview window (issue 807). On every edit, the preview window is reloaded, which occasionally causes scripts to fail to load, which sometimes causes this infinite recursion, hanging the app.

@infusion
Copy link

+1

1 similar comment
@freddie-freeloader
Copy link

+1

@dpvc dpvc added the Accepted Issue has been reproduced by MathJax team label Feb 27, 2018
@dpvc
Copy link
Member

dpvc commented Feb 27, 2018

You are right, failure to load a resource can cause problems like this. Unfortunately, your solution is not the right one, as MathJax uses special "restart" errors to manage loading its external resources, and restarts can occur multiple times within an expression without it representing an error (e.g., if an expression requires loading more than one file, say for an autoloaded component like the table support, and an autoloaded font file to handle unusual characters). Your technique would cause such an expression to be skipped even if the files are being loaded properly. (Also, the expression should not just be skipped, but a Math Processing Error inserted in its place.)

There are several possible ways to approach this. I suspect the best one is to modify the autoload calls in the various output jax to remove themselves before restarting so that if the file doesn't load, the file won't be requested again.

Here's a patch that does that for the CommonHTML output jax:

<script type="text/x-mathjax-config">
MathJax.Hub.Register.StartupHook("CommonHTML Jax Ready",function () {
  var CHTML = MathJax.OutputJax.CommonHTML,
      MML = MathJax.ElementJax.mml,
      MBASE = MML.mbase;

  var AUTOLOAD = MBASE.CHTMLautoload,
      AUTOLOADFILE = MBASE.CHTMLautoloadFile;

  MBASE.Augment({},{
    CHTMLautoload: function () {
      this.toCommonHTML = MBASE.CHTMLautoloadFail;
      AUTOLOAD.call(this);
    },
    CHTMLautoloadFail: function () {
      throw Error("Can't autoload '"+this.type+"'");
    },
    CHTMLautoloadList: {},
    CHTMLautoloadFile: function (name) {
      if (MBASE.CHTMLautoloadList[name]) {
        throw Error("Can't autoload file '"+name+"'");
      }
      MBASE.CHTMLautoloadList[name] = true;
      AUTOLOADFILE.call(this,name);
    }
  });
});
</script>

Of course, if you are using a different output jax, you would need to modify this to refer to the proper jax.

@infusion
Copy link

When is this bug planned to be fixed? I think a lot of people, including myself, are waiting for it.

@dpvc
Copy link
Member

dpvc commented Mar 18, 2018

When is this bug planned to be fixed?

I expect it will be included in the next release. But we just released 2.7.3, so I don't expect another release until the end of the summer.

@dpvc dpvc added this to the A future release milestone Mar 18, 2018
@dpvc dpvc modified the milestones: A future release, MathJax v2.7.4 Mar 29, 2018
dpvc added a commit to dpvc/MathJax that referenced this issue Mar 30, 2018
dpvc added a commit that referenced this issue Mar 30, 2018
Prevent infinite loop if an autoloaded component fails to load.  #1936
@dpvc dpvc added Merged Merged into develop branch and removed Ready for Review labels Mar 30, 2018
@dpvc
Copy link
Member

dpvc commented Mar 30, 2018

==> Merged.

@dpvc dpvc closed this as completed Mar 30, 2018
dpvc added a commit to mathjax/MathJax-test that referenced this issue Mar 30, 2018
@dpvc
Copy link
Member

dpvc commented Mar 30, 2018

== In testsuite
MathMLToDisplay/issue1936-1.html
MathMLToDisplay/issue1936-2.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Accepted Issue has been reproduced by MathJax team Fixed Test Available v2.7
Projects
None yet
Development

No branches or pull requests

4 participants