From octave-maintainers-request at bevo dot che dot wisc dot edu Sat May 16 00:57:13 1998 Subject: Re: Question From: "John W. Eaton" To: Chuck Robey Cc: octave-maintainers at bevo dot che dot wisc dot edu Date: Sat, 16 May 1998 00:55:03 -0500 (CDT) On 15-May-1998, Chuck Robey wrote: | I recompiled libstdc++ with debugging symbols, and I have gotten much | further. First, my libstdc++ is in sync, I checked. I don't load these | things myself, I run a full cvs archive of FreeBSD-current here, and I | was able to verify via cvs-log that it was a virgin import from the gnu | sources, with no patches. | | FreeBSD is (historically and notoriously) slow to upgrade the compiler, | until new versions have a good track record. My guess is that the | upgrade to 2.8.x is at least 3 months away, and I would not be surprised | to find it happens early next year, because the furious pace of locally | inspired changes will not allow too much other instability in the tree | right away. | | I've done more investigation. The SIGBUS occurs in line 198 of | octave.cc (ddd cut'n'paste): | | 196 #endif | 197 | 198 Vprogram_invocation_name = name; | 199 size_t pos = Vprogram_invocation_name.rfind ('/'); | 200 Vprogram_name = (pos == NPOS) | | This calls, indirectly, to libstdc++/std/bastring.cc line 147: | | 146 // _lib.string.cons_ construct/copy/destroy: | 147 basic_string& operator= (const basic_string& str) | 148 { | 149 if (&str != this) { rep ()->release (); dat = str.rep()->grab (); } | 150 return *this; | 151 } | | The release function is in bastring.h line 69: | | 67 charT& operator[] (size_t s) { return data () [s]; } | 68 charT* grab () { if (selfish) return clone (); ++ref; return data ();} | 69 void release () { if (--ref == 0) delete this; } | 70 | 71 inline static void * operator new (size_t, size_t); | | I'm not sure about this, but on entering the function, ref is 1, and | that's the value of this.ref, right? (understand please that I could be | stronger perhaps in C++, sorry). It _looks_ like "this" is being | deleted, then immediately referenced, which would sure cause the SIGBUS. I believe that the `this' that's being deleted is a __bsrep object, not a basic_string object. The assignment operator checks to see that it is not trying to do an assignment to itself. If it is not, it deletes the current contents of the string on the LHS of the operator= (possibly just decrementing the reference count). This part of the operation is done in the rep()->release() function call. Next it grabs a pointer to the data from the string on the RHS of the operator=, assigning it to this->dat. The str.rep()->grab() function call also increments the reference counter. I think the code is ok. Does the following simpler test program work correctly? jwe #include #include string Vprogram_invocation_name; string Vprogram_name; void tryme (const string& name) { Vprogram_invocation_name = name; size_t pos = Vprogram_invocation_name.rfind ('/'); Vprogram_name = (pos == NPOS) ? Vprogram_invocation_name : Vprogram_invocation_name.substr (pos+1); } int main (int argc, char **argv) { tryme (argv[0]); cout << Vprogram_invocation_name << "\n"; cout << Vprogram_name << "\n"; return 0; }