solc-js icon indicating copy to clipboard operation
solc-js copied to clipboard

RuntimeError: abort(Error: <Insert my error here>). Build with -s ASSERTIONS=1 for more info.

Open iAmMichaelConnor opened this issue 4 years ago • 7 comments

Hi!

EDIT: I've created a repo with a minimal example of the bug, for people to try out and confirm: https://github.com/iAmMichaelConnor/solc-error-demo

solc version: 0.7.1 (& tested with 0.7.4) node version: 12.18.2 (& tested with latest lts v15.0.1)

I'm writing a node.js application which imports solc-js in one .mjs file to compile a solidity file and output the AST.

During development, whenever my application breaks and throws an error, the console spits out a solc-related error. Strangely, the solc-related error will throw even for code that isn't using solc. It appears the file ./node_modules/solc/soljson.js is somehow 'wrapping' my error messages.

A consequence of this is that every time my application throws an error, the console is filled with the thousands of lines of code contained in the file ./node_modules/solc/soljson.js.

Below is an example console output upon my app erroring. (Notice that the actual error is unrelated to solc; I'm accidentally pushing to undefined elsewhere in my app. In fact, at this stage of my app's code, solc has been long finished with, and will not be called upon again).

Error: TypeError: Cannot read property 'push' of undefined
Error: TypeError: Cannot read property 'push' of undefined
/Users/em137vl/Documents/git/sprinkles/node_modules/solc/soljson.js:1
null;var Module=typeof Module!=="undefined"?Module:{};var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var arguments_=[];var thisProgram="./this.program";var quit_=function(status,toThrow){throw toThrow};var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;

// I'VE OMITTED THE THOUSANDS OF LINES FROM THE MIDDLE OF `./node_modules/solc/soljson.js`

ledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();preMain();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;function exit(status,implicit){if(implicit&&noExitRuntime&&status===0){return}if(noExitRuntime){}else{ABORT=true;EXITSTATUS=status;exitRuntime();if(Module["onExit"])Module["onExit"](status)}quit_(status,new ExitStatus(status))}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}noExitRuntime=true;run();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            

RuntimeError: abort(Error: TypeError: Cannot read property 'push' of undefined). Build with -s ASSERTIONS=1 for more info.
    at process.abort (~/git/my-project/node_modules/solc/soljson.js:1:13938)
    at process.emit (events.js:315:20)
    at processEmit [as emit] (~/git/my-project/node_modules/signal-exit/index.js:161:32)
    at processPromiseRejections (internal/process/promises.js:209:33)
    at processTicksAndRejections (internal/process/task_queues.js:98:32)

Any ideas to stop solc wrapping errors?

Many thanks!

iAmMichaelConnor avatar Oct 21 '20 17:10 iAmMichaelConnor

Referring to the example demonstration of the bug... It appears what's happening is that the call to solc is actually kicking off two processes: the compile process I'm consciously running (AST generation) and another, hidden one. The hidden one runs async for several seconds after my AST comes back.

You can see this if you remove my run() function and just call compile directly at the top level of the code like this (then you don't have any asyncs):

const ast = compile(solidityFile)
console.log(ast); // showing that solc works

You'll notice that the ast gets printed quickly but Node doesn't terminate for several seconds: it's waiting for that hidden async process to complete. If you error during that time I think it also causes the hidden process to fail and write out all the error stuff. (Thanks to @westlad for this observation).

I wonder if solc actually is generating the AST and then carrying on to make a binary, and the latter is the hidden process?That is after all what you'd expect a 'compile' command to do normally (i.e. not stop at AST creation). Although I don't use that output, perhaps the process still runs?

Is there a way to stop that background process?

iAmMichaelConnor avatar Oct 22 '20 09:10 iAmMichaelConnor

I tried the newest v0.7.4 version of solc, and added the new stopAfter: parsing field to the settings object (thinking that might kill the background process), but the problem persists.

Indeed, if (in the example demonstration), I increase the sleep time to 30 seconds and then throw an error, solc still wraps my errors.

iAmMichaelConnor avatar Oct 22 '20 10:10 iAmMichaelConnor

Thank you for reporting this! This sounds like a problem with the compilation to webassembly.

chriseth avatar Oct 22 '20 12:10 chriseth

Maybe related to https://github.com/ethereum/solc-js/issues/34

chriseth avatar Oct 22 '20 12:10 chriseth

Did you find solution?

yilmazbingo avatar Jun 08 '21 04:06 yilmazbingo

For me, I also tend to run into these problems regularly and the problem is that before, in node.js, it seems something is dumping loads of data into my shell. Can this at least be prevented somehow? It makes debugging any earlier code quite tricky...

https://user-images.githubusercontent.com/2758453/164273596-12c66ed2-ab98-4f9e-bbea-c4aed211058e.mov

TimDaub avatar Apr 20 '22 16:04 TimDaub

Hi @iAmMichaelConnor, @yilmazbingo, and @TimDaub,

I looked at this problem, and apparently, it was fixed on version >=0.8.12. I tested the demo using the recent solcjs versions, and it worked as expected. However, for older binaries (<0.8.12), you may need to use the workaround suggested here: https://github.com/ethereum/solidity/issues/12228 to remove the listener of unhandled Promise rejections.

I.e. adding the following to your code (you can test it with your demo):

const listeners = process.listeners("unhandledRejection");
process.removeListener("unhandledRejection", listeners[listeners.length - 1]);

r0qs avatar Sep 26 '22 10:09 r0qs