|
Reported by Steve Gardner
In multithreaded applications, the UniqueString procedure in the
System unit could perform an invalid memory access or leak memory.
This could lead to rarely occurring bugs in multithreaded
applications.
Justification:
This is not a reproducible bug. The bug is observed from the
assembler code in System.pas.
UniqueString does the following:
- Exits if the string is nil, or the reference count equals 1
- Creates a new destination string
- Uses "LOCK DEC" to decrement the reference count of the source in a
thread-safe way.
- Copies the string contents from source to destination.
Consider the scenario where there are two string variables, A and B,
that refer to the same copy of a string whose reference count is 2,
and one thread calls UniqueString(A) as another thread is executing
"B := C". As A and B are separate variables, this should be an
acceptable thing to do.
After step 3 reduces the reference count to 1, but before step 4
completes, the "B := C" thread could interrupt and release the
contents of the source string. When step 4 resumes, it will be
reading from released memory.
Alternatively, the "B := C" thread could interrupt step 2 and decrease
the reference count to 1. When step 3 executes, it will (correctly)
reduce the reference count to 0, but it will not release the
associated memory.
Note from Jordan Russell:
I marked this bug as "N/A" on Delphi versions prior to 5 because those versions do not have any thread-safe string code.
Delphi 6 & Kylix:
The suggested workaround is almost exactly what was implemented in Delphi 6. I haven't tested, but I assume this means the problem must be solved.
Kylix does not have the FreeMem call, so the memory leak problem potentially still exists there. |