From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM autolearn=unavailable autolearn_force=no version=3.4.4 X-Received: by 2002:a24:e387:: with SMTP id d129mr9829732ith.40.1549137709666; Sat, 02 Feb 2019 12:01:49 -0800 (PST) X-Received: by 2002:aca:5884:: with SMTP id m126mr360286oib.4.1549137709511; Sat, 02 Feb 2019 12:01:49 -0800 (PST) Path: eternal-september.org!reader01.eternal-september.org!feeder.eternal-september.org!2.eu.feeder.erje.net!4.us.feeder.erje.net!feeder.erje.net!feeder.usenetexpress.com!feeder-in1.iad1.usenetexpress.com!border1.nntp.dca1.giganews.com!nntp.giganews.com!k10no436196itk.0!news-out.google.com!v141ni595ita.0!nntp.google.com!k10no436192itk.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Sat, 2 Feb 2019 12:01:49 -0800 (PST) Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=70.109.61.2; posting-account=QF6XPQoAAABce2NyPxxDAaKdAkN6RgAf NNTP-Posting-Host: 70.109.61.2 User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: Subject: Tracing a race condition From: Jere Injection-Date: Sat, 02 Feb 2019 20:01:49 +0000 Content-Type: text/plain; charset="UTF-8" Xref: reader01.eternal-september.org comp.lang.ada:55434 Date: 2019-02-02T12:01:49-08:00 List-Id: 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?