------- Additional Comments From jkanze at cheuvreux dot com 2005-05-03 10:59 ------- Subject: Re: Lack of Posix compliant thread safety in std::basic_string
|> > I'm not sure what sort of help you are looking for. I thought |> > that I very clearly pointed out the problem, and the point in |> > the code where it occured. |> Ok, my message was not clear. I'm looking for help about the |> *performance* issue, not the correctness issue. To your best |> knowledge all those users that avoid v3 basic_string for MT |> applications do that for performance or for correctness (wrt |> the Posix issue that you are pointing out in detail)?? To the best of my knowledge, not very many people avoid basic_string. Most people aren't that aware of threading issues to begin with, and most people just use whatever is there, and suppose that it meets whatever standards are usual for thread-safety on the platform in question. I only started being more wary myself because on two occasions, I've had to "fix" programs which didn't work, because they used the basic_string which came with 2.95.2 -- it just didn't occur to the authors to ask the question whether the library gave the Posix guarantees. The situation with the current library is simple: there is a specific sequence of events which will cause it to use deleted memory, double delete, etc. For that to occur, one thread must access the same object via [], at(), begin() or end(), a second thread must copy the object, and the second thread must interrupt the first thread between the test whether the object is shared, and the moment it is marked as leaked. On a typical machine, that last condition will only last a couple of machine instructions, less than a microsecond. Which means that most of the time, even if the code is incorrect, it will seem to work. And every once in a blue moon, the user will get an unexplicable crash, that the developers cannot duplicate. The problem can be avoided. The easiest (and surest) way is by synchronizing manually; only accessing the global objects to copy them (using the copy constructor) should work as well. (As soon as the representation is shared, the code works. At least in practice on single processor machines; there are no memory barriers around the non-modifying reads, nor around the write of -1 to mark the representation as leaked, which means that some updates may not be correctly seen by threads running on a different processor. Only using copies still works, however; the thread which makes the copy will at least see its update, which results in a reference count greater than 0, which is all that is needed to trigger the deep copy before leaking. Still, it's pretty shaky, and I would have expected anyone familiar with thread safety issues to have ensured that the normal memory barriers were present.) |> Reading |> those papers that I mentioned before (+ another one on C/C++ |> Users Journal which exactly touches *your* issue) it's *not* |> at all clear that the latter is the main issue, in the general |> understanding. I'm not too sure which papers you are referring to, even after Herb Sutter's name was mentionned. I do know that the one article I have read by Herb which concerned thread safety was full of errors, and resulted in a long discussion in comp.lang.c++.moderated. |> > It would help. But an implementation designed with reference |> > counting in mind is likely to be rather slow when reference |> > counting is turned off. IMHO, correct and slow is better than |> > the current situation, but not all compiler users agree. |> Indeed. Of course I'm talking about a *switch* (off by default) |> But, about the correctness point... |> > Most other implementations I'm aware of don't use std::string in |> > exceptions. That would seem to be the best solution. |> Ok, but I don't think we can also change that in the short term |> and not affecting the ABI, we are definitely going to do that in |> v7-branch and I would appreciate if you could advise about the |> best solution among all those proposed (see the thread). |> Returning to our issue, however, do you still believe that a |> switch turning off RC would be useful if we don't change the |> treatment of exceptions? I don't know, maybe we can have |> something simple for that within the present ABI, but I cannot |> make promises and want to have an idea of the amount of work. I'm not sure. As I said, the biggest part of the problem is that people aren't aware of the problem. When it comes down to it, it's not nice, the the necessary work-arounds exist. If there is a new implementation in the pipeline which doesn't have the problem, then I'd probably settle for a couple of prominent warnings, in bold face, in the documentation. Even though users who actually even open the documentation seem in a minority, I'd say that the most important thing is to realize what the situation is, and document it. Thus, for example, in the statement from your FAQ that I quoted, you don't say "like any other resource", you say "unlike other resources, locking is necessary even if no thread modifies", and you use something (bold print, etc.) to draw attention to the fact that the guarantees are less that what one normally expects. Not that that will necessarily help; most of the users I know don't even know that a documentation for g++ exists. It's g++ --help to find out the flags, and basta (if that much). But there are limits to what you have to do to protect the users from themselves. -- James Kanze "This message, including any attachments may contain confidential and privileged material; it is intended only for the person to whom it is addressed. Its contents do not constitute a commitment by Credit Agricole Cheuvreux except where provided for in a written agreement. Credit Agricole Cheuvreux assumes no liability or responsibility for the consequences arising out of a delay and/or loss in transit of this message, or for corruption or other error(s) arising in its transmission and for any misuse or fraudulent use which may be made thereof. If you are not the intended recipient, please contact us and abstain from any disclosure, use or dissemination. To the extent that this message contains research information and/or recommendations, these are provided on the same basis as Credit Agricole Cheuvreux's published research and the recipient must have regard to all disclosures and disclaimers contained therein." -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21334