Why is my Kotlin/JS program failing with "RangeError: Maximum call stack size exceeded"? - graalvm

I’ve written a Kotlin/JS program that is crashing on some JavaScript engines.
It’s crashing on GraalVM like this:
RangeError: Maximum call stack size exceeded
at <js> 839(myprogram.js:394:1174923-1174934)
at <js> e(myprogram.js:394:1175309-1175342)
at <js> 724(myprogram.js:394:1174990-1174995)
at <js> e(myprogram.js:394:1175309-1175342)
at <js> :anonymous(myprogram.js:394:1175222-1175358)
at <js> :program(myprogram.js:394:13041-1175382)
at org.graalvm.polyglot.Context.eval(Context.java:345)
On Duktape it’s failing like this:
com.squareup.duktape.DuktapeException: RangeError: compiler recursion limit (line 1)
at com.squareup.duktape.Duktape.evaluate(Native Method)
at com.squareup.duktape.Duktape.evaluate(Duktape.java:60)
This crash was introduced by upgrading from Kotlin 1.4.10 to 1.6.21.

Kotlin/JS uses a code shrinker in production builds. The code shrinker, Terser, produces very long statements that exceed the default limits of certain compilers.
To fix this problem, configure Terser to produce smaller lines. Create a file, subproject/webpack.config.d/myWebpackConfig.js where subproject is the Gradle module that produces the Kotlin/JS executable.
In that file, paste the following:
config.optimization = config.optimization || {};
const TerserPlugin = require("terser-webpack-plugin");
config.optimization.minimizer = [
new TerserPlugin({
terserOptions: {
compress: {
sequences: 10
},
},
}),
];
Changing the value of the sequences option is the key. The default value, 200, fits 200 logical statements into each line. By scaling this down to 10 Terser emits smaller statements.

You could try and start the Java VM with the -Xss and provide more stack to it, the default seems not to be enough for your usecase.
-Xss8m (or more)

Related

Electron builder fails with: no 'object' file generated

I have a problem with electron-builder since upgrading to Electron 10.1.2. My build now fails at rebuild for keyboard-layout. The rebuild only fails for Windows, not Mac. I don't know where to open this issue so I am asking here :).
My setup:
angular: 9.0.7
electron: 10.1.2
electron-builder: 22.8.x
The problem started when I updated electron from 9.0.0 to 10.1.2. Nothing else changed.
The problem:
When calling electron-builder with command electron-builder.cmd --x64 -p always -w rebuild of keyboard-layout is called as one of the steps as:
> keyboard-layout#2.0.16 install C:\Users\<me>\<dir1>\<dir2>\dist\node_modules\keyboard-layout
> node-gyp rebuild
That fails with:
...
win_delay_load_hook.cc
c:\users\<me>\.electron-gyp\10.1.2\include\node\v8.h(5378): error C2220: warning treated as error - no 'object' file generated (compiling source file ..\src\keyboard-layout-manager-windows.cc) [C:\Users\<me>\<dir1>\<dir2>\dist\node_modules\keyboard-layout\build\keyboard-layout-manager.vcxproj]
c:\users\<me>\.electron-gyp\10.1.2\include\node\v8.h(5378): warning C4309: 'static_cast': truncation of constant value (compiling source file ..\src\keyboard-layout-manager-windows.cc) [C:\Users\<me>\<dir1>\<dir2>\dist\node_modules\keyboard-layout\build\keyboard-layout-manager.vcxproj]
c:\users\<me>\.electron-gyp\10.1.2\include\node\v8.h(5378): error C2220: warning treated as error - no 'object' file generated (compiling source file ..\src\keyboard-layout-manager.cc) [C:\Users\<me>\<dir1>\<dir2>\dist\node_modules\keyboard-layout\build\keyboard-layout-manager.vcxproj]
c:\users\<me>\.electron-gyp\10.1.2\include\node\v8.h(5378): warning C4309: 'static_cast': truncation of constant value (compiling source file ..\src\keyboard-layout-manager.cc) [C:\Users\<me>\<dir1>\<dir2>\dist\node_modules\keyboard-layout\build\keyboard-layout-manager.vcxproj]
Done Building Project "C:\Users\<me>\<dir1>\<dir2>\dist\node_modules\keyboard-layout\build\keyboard-layout-manager.vcxproj" (default targets) -- FAILED.
Done Building Project "C:\Users\<me>\<dir1>\<dir2>\dist\node_modules\keyboard-layout\build\binding.sln" (default targets) -- FAILED.
Build FAILED.
...
What I have tried that DID NOT help:
Change binding.gyp in node_modules/keyboard-layout to (chnages marked with <---):
['OS=="win"', {
"sources": [
"src/keyboard-layout-manager-windows.cc",
],
'msvs_settings': {
'VCCLCompilerTool': {
'ExceptionHandling': 1, # /EHsc
'WarnAsError': 'false', # <--- I chnaged this from true to false
},
},
'msvs_disabled_warnings': [
4018, # signed/unsigned mismatch
2220, # <--- I added this
4244, # conversion from 'type1' to 'type2', possible loss of data
4267, # conversion from 'size_t' to 'type', possible loss of data
4302, # 'type cast': truncation from 'HKL' to 'UINT'
4311, # 'type cast': pointer truncation from 'HKL' to 'UINT'
4530, # C++ exception handler used, but unwind semantics are not enabled
4506, # no definition for inline function
4577, # 'noexcept' used with no exception handling mode specified
4996, # function was declared deprecated
],
}], # OS=="win"
What I have tried that DID help:
Electron 10.x.y updated v8 to 8.5 (Electron 10.0.0 release notes) and looking at line that causes the error (...\.electron-gyp\10.1.2\include\node\v8.h(5378)) I see this:
static constexpr size_t kMaxLength =
internal::kApiSystemPointerSize == 4
? internal::kSmiMaxValue
: static_cast<size_t>(uint64_t{1} << 32); <--- Line 5378
When I compare v8.h files from ...\.electron-gyp\10.1.2\include\node\v8.h and ...\.electron-gyp\9.0.0\include\node\v8.h, there is a change in this exact line.
Same line in old version:
static constexpr size_t kMaxLength = internal::kApiSystemPointerSize == 4
? internal::kSmiMaxValue
: 0xFFFFFFFF;
If I chnage static_cast<size_t>(uint64_t{1} << 32) to 0xFFFFFFFF, build succeedes.
My understanding ends here.
Are the old and new lines not theoretically the same? One shifted for 32 bits results in 0xFFFFFFFF?
What can I do to fix this issue and what could be the reason for this change?
Why is this problem only on Windows?
What I have tried that DID NOT help:
'WarnAsError': 'false' should do the trick; however the error was reported for two different files (..\src\keyboard-layout-manager.cc and ..\src\keyboard-layout-manager-windows.cc) so you'd have to modify the build rules for both of them.
Disabling the warning should help too, but it'd have to be warning 4309 (not 2220) that you need to disable. Again, you'd have to do that for both files (or just for the entire compilation).
Are the old and new lines not theoretically the same? One shifted for 32 bits results in 0xFFFFFFFF?
No, 1 << 32 == 0x100000000 == 0xFFFFFFFF + 1).
What can I do to fix this issue?
turning off 'WarnAsError' should help
turning off warning 4309 should help
reverting that one line in your local checkout should help
using Clang instead of MSVC should help
possibly using a different (newer?) version of MSVC would also help
and what could be the reason for this change?
V8 now allows TypedArrays with up to 2**32 elements, which is one more element than before.
Why is this problem only on Windows?
Because warnings are compiler-specific, and MSVC is only used on Windows.
The weird part is that you're seeing this error in the first place. You compile with --x64; if that does what it sounds like, you should be compiling a 64-bit build, where internal::kApiSystemPointerSize == 8 and size_t has 64 bits just like uint64_t, so in the expression static_cast<size_t>(uint64_t{1} << 32); nothing gets truncated.
Even if for whatever reason this build tried to create a 32-bit build of V8, then the other branch should be taken (internal::kApiSystemPointerSize == 4) and the compiler should be smart enough not to warn about a branch that's statically dead anyway.
At any rate, this seems like a compiler bug/limitation. So appropriate workarounds are to either update your compiler, or disable the erroneous warning.

Read a list from stream using Yap-Prolog

I want to run a (python3) process from my (yap) prolog script and read its output formatted as a list of integers, e.g. [1,2,3,4,5,6].
This is what I do:
process_create(path(python3),
['my_script.py', MyParam],
[stdout(pipe(Out))]),
read(Out, OutputList),
close(Out).
However, it fails at read/2 predicate with the error:
PL_unify_term: PL_int64 not supported
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
BrokenPipeError: [Errno 32] Broken pipe
I am sure that I can run the process correctly because with [stdout(std)] parameter given to process_create the program outputs [1,2,3,4,5,6] as expected.
Weird thing is that when I change the process to output some constant term (as constant_term) it still gives the same PL_int64 error. Appending a dot to the process' output ([1,2,3,4,5,6].) doesn't solve the error. Using read_term/3 gives the same error. read_string/3 is undefined in YAP-Prolog.
How can I solve this problem?
After asking at the yap-users mailing list I got the solution.
Re-compiled YAP Prolog 6.2.2 with libGMP option and now it works. It may also occur in 32-bit YAP.

Woodstox parser works fine in test run in Eclipse, but fails from command line

One of my JUnit tests uses (behind the scenes) the Woodstox parser.
When I run the test from within Eclipse, the test succeeds as expected.
But running the same test on the command line, using
mvn clean test -Dtest=com.example.MyClassTest#someParserTest
results in the test to fail with the following exception messages:
Error on line 114 column 21
SXXP0003: Error reported by XML parser: Invalid UTF-8 middle byte 0x3f (at char #4174, byte #3999)
...
at com.ctc.wstx.io.UTF8Reader.reportInvalidOther(UTF8Reader.java:314)
at com.ctc.wstx.io.UTF8Reader.read(UTF8Reader.java:205)
at com.ctc.wstx.io.ReaderSource.readInto(ReaderSource.java:84)
at com.ctc.wstx.io.BranchingReaderSource.readInto(BranchingReaderSource.java:55)
at com.ctc.wstx.sr.StreamScanner.loadMore(StreamScanner.java:961)
at com.ctc.wstx.sr.BasicStreamReader.readTextSecondary(BasicStreamReader.java:4580)
at com.ctc.wstx.sr.BasicStreamReader.finishToken(BasicStreamReader.java:3657)
at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1063)
at com.ctc.wstx.sax.WstxSAXParser.fireEvents(WstxSAXParser.java:524)
at com.ctc.wstx.sax.WstxSAXParser.parse(WstxSAXParser.java:452)
at net.sf.saxon.event.Sender.sendSAXSource(Sender.java:440)
at net.sf.saxon.event.Sender.send(Sender.java:171)
at net.sf.saxon.jaxp.IdentityTransformer.transform(IdentityTransformer.java:363)
I took a look at the to-be-parsed InputStream. The InputStreams are identical in both cases.
Also, there is no "line 114 column 21" in the InputStream. Line 114 ends on column 11.
How can I investigate what causes the different behavior?
It turned out that a library I used made wrong assumptions about the environment's default character encoding (also called platform's default charset).
In the Eclipse environment, calling Charset.defaultCharset() returned UTF-8, while in the command line environment it returned CP1252.
Many standard and third-party Java APIs behave differently depending on the platform's default charset, among them:
String.getBytes()
ByteArrayOutputStream.toString()
XMLOutputFactory.createXMLStreamWriter(OutputStream stream)
IOUtils.toString(InputStream input)
To resolve my issue, I had to update that library to explicitly use the correct character set:
String.getBytes(StandardCharsets.UTF_8)
ByteArrayOutputStream.toString( StandardCharsets.UTF_8.name() )
XMLOutputFactory.createXMLStreamWriter( OutputStream stream, StandardCharsets.UTF_8.name() )
IOUtils.toString(InputStream input, StandardCharsets.UTF_8)

HHVM non-deterministic behaviour of the typechecker

I've noticed that calling hh_client is not always returning correct result. For example: I have following pieces of code:
backend\ConvertMessage.hh:
<?hh // strict
namespace ApiBackend\ConvertMessage {
enum Status: int {
success = 0;
// ... error codes
};
// ... some other classes
};
other place in project:
throw new \SoapFault(
'Server',
\ApiBackend\ConvertMessage\Status::getNames()[$result->status]
);
Sometimes, after doing some changes in project I get following error message: Could not find static method getNames in type ApiBackend\ConvertMessage\Status (Typing[4090])
When I remove a semicolon after one of closing curly brackets, hh_client stops displaying error. But when I insert semicolon back on its place, typechecker still gives me No errors! message.
This is not the only file that causes this problem - it happens to all enums.
It seems to me that it is problem with some cache of either hh_client or hh_server.
Thanks in advance for helping me with solving this problem (and sorry if my english is not too good).
You are probably using an outdated version of HHVM. This problem sounds an awful lot like this race condition, which was fixed in HHVM 3.5.0 and newer (and was backported into the 3.3.3 LTS release). Notably, 3.4.x still had the bug.
What version of HHVM are you using?

Reconcile Error: Has anyone had problems with truncated error messages?

I'm here again to ask for a help to you. This time I believe that few will respond given the great particularity of the problem which I will relate. I'm starting in the world of DataSnap, and still have things I do not understand how this error I will relate.
My Delphi is XE (version 1, Update1). I am using Postgres which generates error messages in Portuguese (Portuguese Brazil) and for this reason the error messages have accents. The connection components are ZeosLib package.
I am using a dialog box "reconcile error" to display errors arising from the application of updates and to test, I tried to insert a record that already existed, thus violating a unique key and thus displaying the reconcile error dialog.
In the memo of the dialog, the message that appears is truncated, ie cut. Check it out:
ERRO: duplicar valor da chave viola a restrição de unicidade "uc_usu_va_login"
DETAIL: Chave (va_login)=(admin) já existe.
CONTEXT: comando SQL "INSERT INTO USUARIOS (VA_NOME
,VA_LOGIN
,CH
But actually what should be returned is this:
ERRO: duplicar valor da chave viola a restrição de unicidade "uc_usu_va_login"
DETAIL: Chave (va_login)=(admin) já existe.
CONTEXT: comando SQL "INSERT INTO USUARIOS (VA_NOME
,VA_LOGIN
,CH_SENHA
,VA_EMAIL)
VALUES (pVA_NOME
,pVA_LOGIN
,pCH_SENHA
,pVA_EMAIL)"
PL/pgSQL function "idu_usuarios" line 7 at comando SQL
I have done a debug on the server to see if the problem is ZeosLib, but I found that the error message generated on the server is complete, proving that ZeosLib does not truncate the message. Everything is unicode. All strings are WideString (the default) on both my program and in ZeosLib.
As you know, to be thrown on the server, the exception is forwarded to the client, roughly speaking, by DataSnap, and on the client, the Reconcile method of TClientDataSet verify if there were problems and then throw the famous exception EReconcileError that can be handled in the OnReconcileError event of TClientDataSet, therefore I believe that the message is being truncated by DataSnap.
On the client I debug the Reconcile method (DBClient.pas) and immediately before the exception is thrown the flow enters a function within a cpp source code that I think part of the library midas.dll, MidasLib.obj more specifically, since I am using this strategy, not to have to distribute the DLL with my application.
Check(FDSBase.Reconcile_MD(FReconcileDataSet.FDSBase, FDeltaPacket, VarToDataPacket(Results), Integer(Self), RCB));
This call is done at line 1952 of the unit DBClient.pas on Delphi XE Update1. Pressing F7, the debugger enters a source C++ (cpp), so I believe it is within the midaslib.obj. How I do not understand C++ well, I press Shift-F8 to exit the current method and return the next instruction, that is already inside the event OnReconcileError!! Therefore, the truncation must be done within the function I mentioned, within a cpp source, within midaslib.
My intention is to make the Reconcile Error dialog a tool not only for the final user but to support personals, providing separately information of Error, Details and Context. This helps a lot to discover a problem.
The problem now is to make the message appear in full. Has anyone had this kind of problem with messages being truncated by midas?
Also another point DSClient.pas I could extract the error message as it is passed to the exception:
'Erro SQL: ERRO: duplicar valor da chave viola a restrição de unicidade "uc_usu_va_login"'#$A'DETAIL: Chave (va_login)=(admin) já existe.'#$A'CONTEXT: comando SQL "INSERT INTO USUARIOS (VA_NOME'#$A' ,VA_LOGIN'#$A' ,CH'
If you remove the quotes and replace #$A (1 character) by a white space (one character), you will see that the string has exactly 255 characters!!
I also discovered that the "GetErrorString" in dspickle.cpp uses the constant DBIMAXMSGLEN which is defined in bdetypes.h as 127 (half of 255). As we are in the world of Unicode, it would not be a question of increasing this value to 255 in order to have two bytes per character? This is only a guess...
I leave the question in the air because I lack the knowledge to understand C++ :) Who can help, just look at the function implementation "GetErrorString" in dspickle.cpp. There is this:
LoadString((HINSTANCE)hDll, iErrCode, pString, DBIMAXMSGLEN)
pString is the error message and DBIMAXMSGLEN = 127.
Contradicting the opinion of others I decided to tweak further and finally figured out how to increase the number of characters in the "Reconcile" error message. As I thought the problem was in midas.dll, or more specifically the sources that make up the midas dll because the same set of sources can create MidasLib, which does not require a midas dll. To resolve I had to install the Delphi C++ personality to compile the midas.
After finding the line of the error, I discovered that there is even a request for repairs to the QC (http://qc.embarcadero.com/wc/qcmain.aspx?d=84960) which seems to have been ignored by the staff of Embarcadero, as that the "Resolution" as is "Deferred to Next Rel" (Deferred to Next Release) but the request is from 2010 and I'm using Delphi XE which in my opinion should have the solution but here I am correcting by myself ;)
The problem is inside the method "Clone" of the "DSBASE" class, inside source "ds.cpp" at line 2133 (Delphi XE, Update1). Below is the code block. The red line is the problematic line:
// Set the third field for the error string.
LdStrCpy((pCHAR)pFldDes->szName, szdsERRMESSAGE);
pFldDes->iFldType = fldZSTRING;
pFldDes->iUnits1 = 255; // Increased on request.. DBIMAXMSGLEN;
pFldDes++;
Note that it is very interesting the problem line. It has a constant value of 255, which limits the size of the error messages and a comment "Increased on request". Also note that next to the comment, there is a constant DBIMAXMSGLEN, which I had found and already suspected as being responsible for the problem, but as it was not being used I changed the value of DBIMAXMSGLEN but the error message always came without changes. It is worth mentioning that there is a semicolon (;) after DBIMAXMSGLEN which leads me to think that before (I do not know when) this line was one that was just after my fix:
pFldDes->iUnits1 = DBIMAXMSGLEN;
It's as if someone had deliberately set the field value to 255, removing the previous implementation that was really dynamic and seemingly more correct. After performing the replacement of the line I increased the value of DBIMAXMSGLEN to 1024. DBIMAXMSGLEN is declared "bdetypes.h" as a define. After correcting the line went like this:
#define DBIMAXMSGLEN 1024 // Max message len
After these two changes in "ds.cpp" and "bdetypes.h" I build, test, and the result was as expected: the error message was presented in full in the Reconcile dialog.
To the brave who want to try if they have seen this problem, you need the sources of MIDAS, which comes with Delphi from 2010 if I remember correctly. Good luck to all.

Resources