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

Stackoverflow in RascalMPL while running the test framework #1920

Open
BlackHart98 opened this issue Feb 28, 2024 · 17 comments
Open

Stackoverflow in RascalMPL while running the test framework #1920

BlackHart98 opened this issue Feb 28, 2024 · 17 comments
Labels

Comments

@BlackHart98
Copy link

I encountered this exception while testing my pretty printer module in rascal:

java.lang.StackOverflowErrorjava.lang.StackOverflowError                                  
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowErrorjava.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.NoClassDefFoundError: Could not initialize class java.lang.StackTraceElement$HashedModules
(internal error)
        at $shell$(|main://$shell$|)

java.lang.NoClassDefFoundError: Could not initialize class java.lang.StackTraceElement$HashedModules
/ testing 1/3 error: testAlterV @ |file:///Users/pius/Desktop/Dev/ptlbase/ptlbase/src/lang/spark/prettyprint/Tests.rsc|(444,123,<17,0>,<20,1>)
        Could not initialize class java.lang.StackTraceElement$HashedModules
java.lang.NoClassDefFoundError: Could not initialize class java.lang.StackTraceElement$HashedModules
Unexpected (uncaught) exception, closing the REPL: 
java.lang.NoClassDefFoundError: Could not initialize class java.lang.StackTraceElement$HashedModulesjava.lang.NoClassDefFoundError: Could not initialize class java.lang.StackTraceElement$HashedModules
java.io.IOException: Stream closed
Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class java.lang.StackTraceElement$HashedModules

Exception: java.lang.NoClassDefFoundError thrown from the UncaughtExceptionHandler in thread "main"

I only get this issue when increased the number of test. If you need a link to the project I am willing to provide that.

  • Context: VSCode plugin, Command-line REPL
  • Rascal Version 0.33.7, stable
@DavyLandman
Copy link
Member

I think it would be nice to share your project, as quite some stuff is going wrong here.

@BlackHart98
Copy link
Author

BlackHart98 commented Feb 28, 2024 via email

@BlackHart98
Copy link
Author

Here is the like to the project

https://github.com/BlackHart98/sqlpolyglot/blob/main/src/main/rascal/spark/prettyprint/Tests.rsc#L8

@DavyLandman
Copy link
Member

Does it also happen if you call testCreateDB() directly?

@jurgenvinju
Copy link
Member

I reproduced the behavior. The stackoverflows happen when this test is called:

test bool testAlterV() {
  loc file = |project://sqlpolyglot/src/main/rascal/spark/examples/alterv.ssql|;
  return prettyCond(file);
}

if I remove this test, everything runs smoothly.

@jurgenvinju
Copy link
Member

The trigger is this definition which results in an infinite recursion:

public str toString(ViewId viewId)="<toString(viewId)>";

I found this by setting :set debugging true in VScode and stepping through the code (with "step into"), until I got stuck myself in this place :-)

The stackoverflow error thus genuine, so that's not the bug, but the report of this stackoverflow is bad. It should have given a stack trace like so:

...  toString(ViewId viewId)
...  toString(ViewId viewId)
...  toString(ViewId viewId)
...  toString(ViewId viewId)
...  toString(ViewId viewId)
...

Such than easy diagnosis can be made. I'll look into fixing that in the Rascal interpreter. In the mean time this definition would be a good workaround:

public str toString(propRef(list[Identifier] ids))="<for (id <- ids) {><id> <}>"[..-1];

@jurgenvinju
Copy link
Member

Looks like an interesting project @BlackHart98 !

@jurgenvinju
Copy link
Member

Simple reproduction:

rascal>int f(int i) = f(i);
int (int): function(|prompt:///|(0,20,<1,0>,<1,20>))
rascal>f(2)
java.lang.StackOverflowErrorjava.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.StackOverflowError
java.lang.NoClassDefFoundError: Could not initialize class java.lang.StackTraceElement$HashedModules
(internal error)
        at $shell$(|main://$shell$|)

java.lang.NoClassDefFoundError: Could not initialize class java.lang.StackTraceElement$HashedModules
Unexpected (uncaught) exception, closing the REPL: 
java.lang.NoClassDefFoundError: Could not initialize class java.lang.StackTraceElement$HashedModulesjava.lang.NoClassDefFoundError: Could not initialize class java.lang.StackTraceElement$HashedModules
java.io.IOException: Stream closed
Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class java.lang.StackTraceElement$HashedModules

Exception: java.lang.NoClassDefFoundError thrown from the UncaughtExceptionHandler in thread "main"

@jurgenvinju
Copy link
Member

The problem seems to be this code which catches the StackOverflowError just below the deepest stack frame, and then calls more code which needs stack space to print the error:

In Expression.CallOrTree.interpret():

catch (StackOverflowError e) {
				e.printStackTrace();
				throw RuntimeExceptionFactory.stackOverflow(this, eval.getStackTrace());
			}

@BlackHart98
Copy link
Author

The trigger is this definition which results in an infinite recursion:

public str toString(ViewId viewId)="<toString(viewId)>";

I found this by setting :set debugging true in VScode and stepping through the code (with "step into"), until I got stuck myself in this place :-)

The stackoverflow error thus genuine, so that's not the bug, but the report of this stackoverflow is bad. It should have given a stack trace like so:

...  toString(ViewId viewId)
...  toString(ViewId viewId)
...  toString(ViewId viewId)
...  toString(ViewId viewId)
...  toString(ViewId viewId)
...

Such than easy diagnosis can be made. I'll look into fixing that in the Rascal interpreter. In the mean time this definition would be a good workaround:

public str toString(propRef(list[Identifier] ids))="<for (id <- ids) {><id> <}>"[..-1];

Yeah figured that out belatedly, but like you said the report is bad but is genuine

@jurgenvinju
Copy link
Member

Thinking about the fix now. not so easy :-) I need to get some stack space to create the error, but I also need the information on the stack to create the error message.

@BlackHart98
Copy link
Author

Looks like an interesting project @BlackHart98 !

I also noticed that Rascal resolves the project a lot slower, hat could be the issue?

jurgenvinju added a commit that referenced this issue Feb 29, 2024
* stackoverflow errors were not reported properly. Instead the
  interpreter triggered many more stackoverflow errors while trying to
  report on them.
* fixed this by capturing the deepest overflow exception and wrapping
  the current runtime stack in a cheap exception object. This object is
  then thrown an caught by the REPL loop which prints the proper
  exception stack trace.
* We lost the ability to catch a stackOverflow() exception in Rascal
  code with this. This is problematic since there are tools that use
  that (drAmbiguity) in case of expected eternal recursions. So for now
  this is PR and I would like to hear if anybody has ideas on how to fix
  this properly without loss of this important feature.
@jurgenvinju
Copy link
Member

@BlackHart98 I don't know. What do you mean by "resolves the project". Is that the code for starting a terminal or when you read a file with the project:/// scheme? or something else? It's unrelated to this I think, but could also be interesting to look at in a different issue :-)

Thanks for reporting this one anyway. The solution is underway but I need some advice from @DavyLandman to finalize it.

@BlackHart98
Copy link
Author

@BlackHart98 I don't know. What do you mean by "resolves the project". Is that the code for starting a terminal or when you read a file with the project:/// scheme? or something else? It's unrelated to this I think, but could also be interesting to look at in a different issue :-)

Thanks for reporting this one anyway. The solution is underway but I need some advice from @DavyLandman to finalize it.

Maybe my choice of word was wrong, what I meant is the it takes time to load the rascal project after I save changes(on VSCode)

@jurgenvinju
Copy link
Member

Ah yes. No that's a "feature" of the slow type-checker. The more modules you edit, the more it needs to type-check and the slower it becomes. We are working on a compiled version of that as we speak to make that faster.

@jurgenvinju
Copy link
Member

If you keep the .tpl files in your target folder, the type-checker will reuse as much as possible. So that helps. I'd put the target folder in your .gitignore and remove it from git with git rm -r target. That way the time stamps of the .tpl files stay in order when you git pull or git push and you have less work for the typechecker usually.

@BlackHart98
Copy link
Author

Thanks, :-)

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

No branches or pull requests

3 participants