octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Question


From: John W. Eaton
Subject: Re: Question
Date: Sat, 16 May 1998 00:55:03 -0500 (CDT)

On 15-May-1998, Chuck Robey <address@hidden> 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 <string>
#include <iostream.h>

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;
}



reply via email to

[Prev in Thread] Current Thread [Next in Thread]