On 28.07.2025 16:49, Rick McGuire wrote:
Once again, you didn't bother reading what I told you.
Why do you say that as it is not true? (I have always appreciated your
expertise and help.)
Under NO circumstances should you be altering the instance variable in
tmpInstance.
AFAIK I am *not* doing that!
Here the class definitions from Interpreter.hpp for InstanceBLock and InstanceAttacherDetacher, both
define a public field named instance:
class InstanceBlock
{
public:
InstanceBlock();
InstanceBlock(RexxOption *options);
InstanceBlock(PRXSYSEXIT exits, const char *env);
~InstanceBlock();
Activity *activity; // our current activity
/InterpreterInstance *instance; // potential interpreter instance/
};
class InstanceAttacherDetacher
{
public:
InstanceAttacherDetacher(InterpreterInstance *i);
~InstanceAttacherDetacher();
**/InterpreterInstance *instance; // interpreter instance/
};
Here the implementation of InstanceAttacherDetacher:
/**
* Make sure that attachThread() and detachThread() get carried out for the
* supplied InterpreterInstance.
*
* @param i InterpreterInstance
*/
InstanceAttacherDetacher::InstanceAttacherDetacher(InterpreterInstance *i)
{
// Get an instance.
instance = i;
instance->InterpreterInstance::attachThread();
}
/**
* Carry out detachThread() for the instance, if going out of scope.
*/
InstanceAttacherDetacher::~InstanceAttacherDetacher()
{
// detach from the instance
instance->InterpreterInstance::detachThread();
}
Here the code where tmpInstance's field gets referred to, but not changed:
// the resource lock needs to be released here because unloading
packages
// will require the kernel lock, which can never be requested while
holding
// the resource lock
try
{
// this may seem funny, but we need to create an instance
// to shut down so that the package manager can unload
// the libraries (it needs to pass a RexxThreadContext
// pointer out to package unloaders, if they are defined)
InstanceBlock tmpInstance;
*// make sure that attaching and detaching is done for this
particular block {*
InstanceAttacherDetacher instAttDet(*tmpInstance.instance*);
// run whatever uninits we can before we start releasing the
libraries
memoryObject.lastChanceUninit();
PackageManager::unload();
*}*
}
catch (ActivityException)
{
// we're shutting down, so ignore any failures while processing this
}
Where would a tmpInstance variable get changed?
Maybe I am not seeing the forest for the trees.
I'm not sure that's the cause of the problem, but that would be a very, very, bad thing to do and
it gains you nothing.
And of course, I would not want to do that at all!
---rony
On Mon, Jul 28, 2025 at 10:11 AM Rony G. Flatscher <rony.flatsc...@wu.ac.at>
wrote:
On 28.07.2025 15:02, Rony G. Flatscher wrote:
On 28.07.2025 13:51, Rick McGuire wrote:
You broke, you fix it.
:)
But having said that, I see one obvious problem. Updating the instance
field of an
InstanceBlock is a very, very, very bad idea. That was a new interpreter
instance that was
created for that block of code that will be automatically removed when it
goes out of scope.
Changing this means a) you are preventing that instance from getting
cleaned up when it's
supposed to, and b) when the destructor runs, you are cleaning up the
instance that has
already been detached. The dispatching internals are going to be seriously
messed up.
Thanks. Enclosed the code in a proper block to make sure that the instance
is available:
// the resource lock needs to be released here because unloading
packages
// will require the kernel lock, which can never be requested
while holding
// the resource lock
try
{
// this may seem funny, but we need to create an instance
// to shut down so that the package manager can unload
// the libraries (it needs to pass a RexxThreadContext
// pointer out to package unloaders, if they are defined)
InstanceBlock tmpInstance;
*// make sure that attaching and detaching is done for this
particular block {*
InstanceAttacherDetacher instAttDet(tmpInstance.instance);
// run whatever uninits we can before we start releasing
the libraries
memoryObject.lastChanceUninit();
PackageManager::unload();
*}*
}
catch (ActivityException)
{
// we're shutting down, so ignore any failures while
processing this
}
Ran the testsuite on Windows and it did not crash anymore, hence planning
to commit this
version to see how it fares on the Jenkins farm.
Well, that was just by coincidence that it did not crash.
My understanding from C++ would be that the block in which InstanceBlock
tmpInstance is
defined is the outer block relative to the new block in which
InstanceAttacherDetacher
instAttDet(tmpInstance.instance) gets defined and accesses tmpInstance's
instance. If the
inner block is left then the InstanceAttacherDetacher destructor gets
invoked before arriving
in the outer block such that the InstanceBlock destructor gets run
afterwards when the outer
block is left.
If that is not a safe solution, what would be one?
---rony
_______________________________________________
Oorexx-devel mailing list
Oorexx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-devel