* Tracing a race condition
@ 2019-02-02 20:01 Jere
2019-02-02 20:52 ` Dmitry A. Kazakov
0 siblings, 1 reply; 2+ messages in thread
From: Jere @ 2019-02-02 20:01 UTC (permalink / raw)
I was running a rather large code base which on rare occasion
throws a PROGRAM_ERROR "finalize/adjust raised exception". After
working on it some time, I narrowed it down to a call to Release
in the Object package of Dmitry's simple components. This narrows
the problem down to at least a couple of options (maybe more):
1. An object that a task has an access to goes out of scope early
2. A potential race condition in the Release procedure
I am still trying to trace through the code (not mine, so learning
how it works) to verify the status of #1. I did take a look at #2 as
well though. Here is the Entity type and the Release procedure:
***************************
type Entity is new Ada.Finalization.Limited_Controlled with record
Use_Count : Natural := 0; -- Reference count
end record;
type Entity_Ptr is access all Entity'Class;
***************************
***************************
procedure Release (Ptr : in out Entity_Ptr) is
procedure Free is new
Ada.Unchecked_Deallocation (Entity'Class, Entity_Ptr);
begin
if Ptr /= null then
declare
Object : Entity'Class renames Ptr.all;
begin
Decrement_Count (Object);
if Object.Use_Count > 0 then
return;
end if;
end;
Free (Ptr);
end if;
end Release;
***************************
Source: http://www.dmitry-kazakov.de/ada/components_4_38.tgz
Decrement_Count simply calls a protected procedure to update
the Use_Count field of the Object.
I think what is happening is Task A calls a series of code
that eventually causes a call to Release on an object and
so does Task B. When that happens, there is a small chance
of the following situation:
Task A: Decrement_Count(Object); -- Use_Count goes down to 1
Task A gives up its time slot
Task B resumes
Task B: Decrement_Count(Object); -- Use_Count goes down to 0
Task B: if Object.Use_Count > 0 then -- skips this since 0
...
Task B: Free(Ptr); -- This free is logically wrong (early)
...
Task B gives up its time slot
Task A resumes
Task A: if Object.Use_Count > 0 then -- skips this since 0
...
Task A: Free(Ptr); -- This free causes the exception (I think)
That doesn't mean that the #1 scenario isn't also a problem, but
I am still looking at it to verify. In the mean time, is this
a potential race condition in the Release procedure?
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: Tracing a race condition
2019-02-02 20:01 Tracing a race condition Jere
@ 2019-02-02 20:52 ` Dmitry A. Kazakov
0 siblings, 0 replies; 2+ messages in thread
From: Dmitry A. Kazakov @ 2019-02-02 20:52 UTC (permalink / raw)
On 2019-02-02 21:01, Jere wrote:
> I think what is happening is Task A calls a series of code
> that eventually causes a call to Release on an object and
> so does Task B. When that happens, there is a small chance
> of the following situation:
>
> Task A: Decrement_Count(Object); -- Use_Count goes down to 1
> Task A gives up its time slot
> Task B resumes
> Task B: Decrement_Count(Object); -- Use_Count goes down to 0
> Task B: if Object.Use_Count > 0 then -- skips this since 0
> ...
> Task B: Free(Ptr); -- This free is logically wrong (early)
> ...
> Task B gives up its time slot
> Task A resumes
> Task A: if Object.Use_Count > 0 then -- skips this since 0
> ...
> Task A: Free(Ptr); -- This free causes the exception (I think)
>
> That doesn't mean that the #1 scenario isn't also a problem, but
> I am still looking at it to verify. In the mean time, is this
> a potential race condition in the Release procedure?
I seems so. Though Natural is passed by value, its container object is
by reference. Thanks for catching it. I am going to fix that.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2019-02-02 20:52 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-02 20:01 Tracing a race condition Jere
2019-02-02 20:52 ` Dmitry A. Kazakov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox