comp.lang.ada
 help / color / mirror / Atom feed
* 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