As the ProgressBar test case is probably the best test case to demonstrate and
analyze the crashes
with relative few native calls between Rexx interpreter instances and Java, I
tried to make it even
easier to help debug the cause. There is also information on the callback count
from Java when
crashes occur the earliest and when they occur usually, if they occur at all
(running
startTestProgressBar.rex).
Also, it may be helpful to have a version that usually does not crash (running
startTestProgressBar-using-HotFix.rex). The reason seems to be that with using
a Sleep() of 1/100
second before doing an AttachThread().
The debug output may be overwhelming at first, but shows the TID (thread ID)
and the RIID (Rexx
interpreter instance ID) which allows one to analyze the flow of control and
which RIIDs are being
employed in which TID.
---
Today I created a new version of this test case (32-bit Windows), which allows
one to choose the
nondebug or the debug output version of BSF4ooRexx.dll:
* runTest.bat ... uses nondebug-output version of
BSF4ooRexx.dll
* runTestWithDebugOutput.bat ... uses debug-output version of BSF4ooRexx.dll
To get the version that crashes, open a new window (sometimes, if a run was
without crashes running
the script in the same session again won't crash) and enter one of:
* runTest.bat startTestProgressBar.rex
* runTestWithDebugOutput.bat startTestProgressBar.rex
o if a crash occurs then the earliest point is at the 37th callback from
Java into Rexx
(invoking BSF4ooRexx function
"Java_org_rexxla_bsf_engines_rexx_RexxAndJava_jniRexxSendMessageToRexxObject()"
via native
code using JNI), the crashes usually appear between the 40th and 42nd
callback from Java;
maybe this helps in debugging when setting a breakpoint at the static
local variable "count"
in that function.
Running "startTestProgressBar-using-HotFix.rex" usually does not crash; this
version relinquishes
control before doing an AttachThread() in _jniRexxSendMessageToRexxObject():
* runTest.bat startTestProgressBar-using-HotFix.rex
* runTestWithDebugOutput.bat startTestProgressBar-using-HotFix.rex
---
To run these tests there is no need to install BSF4ooRexx as the zip-archive
contains all necessary
files and scripts to set up the environment to allow this test case to run. The
only prerequisite is
32-bit ooRexx on Windows and 32-bit Java (from
<https://java.com/en/download/manual.jsp>, entitled:
"Windows Online" or "Windows Offline") installed.
Link:
* 20170925-testApp.zip:
<https://www.dropbox.com/s/1gfpj4ap67qvr2l/20170925-testApp.zip?dl=0>;
unzip it and run one of the above scripts
---rony
On 24.09.2017 13:28, Rony G. Flatscher wrote:
>
> In the past days I have been testing/experimenting with the crashes on my
> ProgressBar example. Two
> observations that may be helpful:
>
> * Changing the usage of Rexx interpreter instances (RII) slightly: for the
> RexxScript
> (javax.script) implementation there is a RexxScriptFactory class that
> supplies various Rexx
> related information, including the currently installed/used version of
> ooRexx. In order to
> fetch the version information a proper RexxEngine (using only the
> long-standing and long
> tested Apache BSF framework) gets created carrying out a "parse version
> v; return v" which
> then is used to fill in each RexxScript (javax.script) engine instance.
> This RexxEngine gets
> now explicitly terminated thereafter.
>
> * Observations
> o activating debug messages (using "fprintf(stderr,..)" followed by
> "fflush(stderr);") from
> the BSF4ooRexx.cc ("#define INFO_ALL_OPTIONS") code all of a sudden
> makes the test script
> run through without causing any crashes anymore (before the change to
> the BSF RexxEngine
> usage crashes would occur here as well)!
>
> o removing debug messages, causes crashes again:
>
> + one exception I got was in "> rexx.dll!DeadObject::remove()
> Line 112 C++", where
> the "next" field in the remove() function is NULL, such that
> "next->previous =
> this->previous;" causes the exception
>
> + most of the crashes (with different messageName values) occur in:
> > rexx.dll!MethodDictionary::getMethod(RexxString *
> methodName=0x7edba910) Line
> 69 C++
> > rexx.dll!RexxBehaviour::methodLookup(RexxString *
> messageName=0x7edba910) Line
> 432 C++
> ... cut ...
>
> in RexxBehaviour::methodLookup():
>
> "MethodClass *method =
> methodDictionary->getMethod(messageName);", where
> "methodDictionary" is NULL when crashing in
> MethodDictionary::getMethod()
>
>
> + maybe a coding error, here the crash:
> > rexx.dll!NativeActivation::setDigits(long _digits=18) Line
> 2133 C++
> > rexx.dll!RexxInstructionNumeric::execute(RexxActivation *
> context=0x7e0d4078,
> ExpressionStack * stack=0x7e0d4140) Line 106 C++
> > rexx.dll!RexxActivation::run(RexxObject *
> _receiver=0x7e0be058, RexxString *
> name=0x7dfd3998, RexxObject * * _arglist=0x7d8ab04c, unsigned int
> _argcount=0,
> RexxInstruction * start=0x00000000, ProtectedObject &
> resultObj={...}) Line 620 C++
>
> NativeActivation::setDigits has the following code (lines
> 2128-2135):
> void NativeActivation::setDigits(wholenumber_t _digits)
> {
> // if we're in a call context, set this
> if (activation == OREF_NULL) // <--- line # 2133: if
> activation==NULL, then the following statement crashes!
> {
> activation->setDigits(_digits);
> }
> }
>
>
> + "Debug Error!"
> ---------------------------
> Microsoft Visual C++ Runtime Library
> ---------------------------
> Debug Error!
>
> Program: C:\Program Files (x86)\ooRexx\rexx.dll
> Module: C:\Program Files (x86)\ooRexx\rexx.dll
> File:
> g:\oorexx.tmp\oorexxsvn\main\trunk\interpreter\classes\support\hashcollection.cpp
> Line: 426
>
> Run-Time Check Failure #0 - The value of ESP was not properly
> saved across a function
> call. This is usually a result of calling a function declared
> with one calling
> convention with a function pointer declared with a different
> calling convention.
>
> (Press Retry to debug the application)
>
> ---------------------------
> Abort Retry Ignore
> ---------------------------
>
> Here is the relevant part of the stack trace:
> rexx.dll!failwithmessage(void * retaddr=0x6acb067e, int
> crttype=1, int errnum=0, const char * msg=0x6ae82118) C++
> rexx.dll!_RTC_Failure(void * retaddr=0x6acb067e, int errnum=0)
> C++
> rexx.dll!_RTC_CheckEsp() C++
> > rexx.dll!HashCollection::put(RexxInternalObject *
> value=0x7e0f3790, RexxInternalObject * index=0x7dbb6a98) Line 427 C++
> rexx.dll!RexxActivation::trapOn(RexxString *
> condition=0x7dbb6a98, RexxInstructionTrapBase * handler=0x7dc89d38, bool
> signal=true) Line 1433 C++
> rexx.dll!RexxInstructionSignalOn::execute(RexxActivation *
> context=0x7e0f3488, ExpressionStack * stack=0x7e0f3550) Line 311 C++
> rexx.dll!RexxActivation::run(RexxObject * _receiver=0x7dcbd1d0,
> RexxString * name=0x7dc89598, RexxObject * * _arglist=0x7d8ab0f4, unsigned
> int _argcount=1, RexxInstruction * start=0x00000000, ProtectedObject &
> resultObj={...}) Line 620 C++
> ... cut ...
>
> ---
>
> The case where the program runs successfully to the end (with maybe
> interesting debug information)
> can be downloaded as a zip-file from
> <https://www.dropbox.com/s/2ohch3iy024acxc/20170923-testApp.zip?dl=0>. To run
> the program just
> enter "runTest startTestProgressBar.rex" or "runTest
> startTestProgressBar-using-HotFix.rex", no
> need to install BSF4ooRexx. The only prerequisite as mentioned in the
> "readme.txt" file is a
> 32-bit of Java be installed (from <https://java.com/en/download/manual.jsp>,
> entitled: "Windows
> Online" or "Windows Offline"); it is possible to have 64- and 32-bit Java
> installed at the same
> time on Windows.
>
> ---rony
>
> P.S.: Because the crashes are caused most often in
> MethodDictionary::getMethod, here is an example
> stack trace:
>
> rexx.dll!MethodDictionary::getMethod(RexxString *
> methodName=0x7edc7908) Line 69 C++
> > rexx.dll!RexxBehaviour::methodLookup(RexxString *
> messageName=0x7edc7908) Line 432 C++
> rexx.dll!RexxObject::messageSend(RexxString * msgname=0x7edc7908,
> RexxObject * * arguments=0x7d8ab164, unsigned int count=1, ProtectedObject &
> result={...}) Line 815 C++
> rexx.dll!ExpressionStack::send(RexxString * message=0x7edc7908,
> unsigned int count=1, ProtectedObject & result={...}) Line 80 C++
> rexx.dll!RexxExpressionMessage::evaluate(RexxActivation *
> context=0x7e0c3378, ExpressionStack * stack=0x7e0c3440) Line 191 C++
> rexx.dll!RexxInstructionAssignment::execute(RexxActivation *
> context=0x7e0c3378, ExpressionStack * stack=0x7e0c3440) Line 129 C++
> rexx.dll!RexxActivation::run(RexxObject * _receiver=0x7dcbd1d0,
> RexxString * name=0x7dc89598, RexxObject * * _arglist=0x7d8ab0f4, unsigned
> int _argcount=1, RexxInstruction * start=0x00000000, ProtectedObject &
> resultObj={...}) Line 620 C++
> rexx.dll!RexxCode::run(Activity * activity=0x7e06eb80, MethodClass *
> method=0x7dc8bbe0, RexxObject * receiver=0x7dcbd1d0, RexxString *
> msgname=0x7dc89598, RexxObject * * argPtr=0x7d8ab0f4, unsigned int
> argcount=1, ProtectedObject & result={...}) Line 212 C++
> rexx.dll!MethodClass::run(Activity * activity=0x7e06eb80, RexxObject *
> receiver=0x7dcbd1d0, RexxString * msgname=0x7dc89598, RexxObject * *
> argPtr=0x7d8ab0f4, unsigned int count=1, ProtectedObject & result={...}) Line
> 170 C++
> rexx.dll!RexxObject::messageSend(RexxString * msgname=0x7dc89598,
> RexxObject * * arguments=0x7d8ab0f4, unsigned int count=1, ProtectedObject &
> result={...}) Line 839 C++
> rexx.dll!ExpressionStack::send(RexxString * message=0x7dc89598,
> unsigned int count=1, ProtectedObject & result={...}) Line 80 C++
> rexx.dll!RexxExpressionMessage::evaluate(RexxActivation *
> context=0x7e0c2fd0, ExpressionStack * stack=0x7e0c3098) Line 191 C++
> rexx.dll!RexxInstructionAssignment::execute(RexxActivation *
> context=0x7e0c2fd0, ExpressionStack * stack=0x7e0c3098) Line 129 C++
> rexx.dll!RexxActivation::run(RexxObject * _receiver=0x7dcbd1d0,
> RexxString * name=0x7dfd2d08, RexxObject * * _arglist=0x7d8ab04c, unsigned
> int _argcount=4, RexxInstruction * start=0x00000000, ProtectedObject &
> resultObj={...}) Line 620 C++
> rexx.dll!RexxCode::run(Activity * activity=0x7e06eb80, MethodClass *
> method=0x7dc8d1a8, RexxObject * receiver=0x7dcbd1d0, RexxString *
> msgname=0x7dfd2d08, RexxObject * * argPtr=0x7d8ab04c, unsigned int
> argcount=4, ProtectedObject & result={...}) Line 212 C++
> rexx.dll!MethodClass::run(Activity * activity=0x7e06eb80, RexxObject *
> receiver=0x7dcbd1d0, RexxString * msgname=0x7dfd2d08, RexxObject * *
> argPtr=0x7d8ab04c, unsigned int count=4, ProtectedObject & result={...}) Line
> 170 C++
> rexx.dll!RexxObject::messageSend(RexxString * msgname=0x7dfd2d08,
> RexxObject * * arguments=0x7d8ab04c, unsigned int count=4, ProtectedObject &
> result={...}) Line 839 C++
> rexx.dll!ExpressionStack::send(RexxString * message=0x7dfd2d08,
> unsigned int count=4, ProtectedObject & result={...}) Line 80 C++
> rexx.dll!RexxInstructionMessage::execute(RexxActivation *
> context=0x7e063f60, ExpressionStack * stack=0x7e064028) Line 188 C++
> rexx.dll!RexxActivation::run(RexxObject * _receiver=0x7dfd5d08,
> RexxString * name=0x7dfcf4a0, RexxObject * * _arglist=0x7d8ab0e8, unsigned
> int _argcount=1, RexxInstruction * start=0x00000000, ProtectedObject &
> resultObj={...}) Line 620 C++
> rexx.dll!RexxActivation::dispatch() Line 441 C++
> rexx.dll!Activity::runThread() Line 208 C++
> rexx.dll!dispatch_activity_function(void * arguments=0x7e06eb80) Line
> 65 C++
> kernel32.dll!74b0336a() Unknown
> [Frames below may be incorrect and/or missing, no symbols loaded for
> kernel32.dll]
> ntdll.dll!77059902() Unknown
> ntdll.dll!770598d5() Unknown
>
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Oorexx-devel mailing list
Oorexx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-devel