www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - append to immutable array segfaults - anyone else seen it?

reply Adam D. Ruppe <destructionator gmail.com> writes:
One of my apps, seemingly at random, started crashing today. The
part at fault looked mostly like this:

===
   immutable(string[])[] records;

   foreach(immutableData; inputSource)
       records ~= [immutableData[1], immutableData[0]];
===

Nothing really fancy there except most everything was immutable. It
worked fine for a while. All my attempts to reduce it to a small
test case fail; the code works there too.

But, for some reason, the live code failed.


Looking into a debugger told me the segfault happened on lifetime.d
line 1967 in druntime:

/**
 * The old way, obsolete.
 */
extern (C) void* _d_arrayliteralT(TypeInfo ti, size_t length, ...)
{
    auto sizeelem = ti.next.tsize();            // array element size
    void* result;


It crashes on the array element size line. Neither ti nor ti.next
were null - both appeared to be valid references.


I changed from an array literal to a temporary object, and got
the same segfault, although in a different function. This, time,
it was here:

/**
 * Append y[] to array x[]
 */
extern (C) void[] _d_arrayappendT(TypeInfo ti, ref byte[] x, byte[] y)
{
    auto length = x.length;
    auto sizeelem = ti.next.tsize();            // array element size




Since the problem was consistently related to typeinfo, I did a hack
fix:

===
   string[][] records;

   foreach(immutableData; inputSource)
       records ~= cast(string[]) [immutableData[1], immutableData[0]];
===

That is: I casted away immutable, and everything works now.




The reason I'm in the newsgroup rather than the bugzilla is I really
have no idea what's going on here. Since I can't recreate it
in a minimal test, that makes it all the harder.


Of all the D2 features, I've had the most trouble, by far, with
immutable array typeinfos randomly disappearing...


Has anyone else seen this? While my cast papers over the immediate
problem, I'd really like to get to the bottom of it and fix it
permanently.

If no one else has seen it, it might be a bug in my code, memory
corruption or something, but it seems awfully unlikely that memory
corruption would always hit a typeinfo structure like I've seen.
May 24 2011
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 24 May 2011 18:02:19 -0400, Adam D. Ruppe  
<destructionator gmail.com> wrote:

 One of my apps, seemingly at random, started crashing today. The
 part at fault looked mostly like this:

 ===
    immutable(string[])[] records;

    foreach(immutableData; inputSource)
        records ~= [immutableData[1], immutableData[0]];
 ===

 Nothing really fancy there except most everything was immutable. It
 worked fine for a while. All my attempts to reduce it to a small
 test case fail; the code works there too.

 But, for some reason, the live code failed.


 Looking into a debugger told me the segfault happened on lifetime.d
 line 1967 in druntime:

 /**
  * The old way, obsolete.
  */
 extern (C) void* _d_arrayliteralT(TypeInfo ti, size_t length, ...)
 {
     auto sizeelem = ti.next.tsize();            // array element size
     void* result;


 It crashes on the array element size line. Neither ti nor ti.next
 were null - both appeared to be valid references.
Are you doing anything with dynamic libraries? I think that dynamic libraries can have their own copies of the typeinfo, which might be invalid if you unload the library. I can't think of any other reason why a typeinfo would "go away". There's always the possibility of memory corruption. -Steve
May 24 2011
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
Steven Schveighoffer:
 Are you doing anything with dynamic libraries?
None, except for the standard C library. It's pretty puzzling.
May 24 2011
parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 24 May 2011 18:26:52 -0400, Adam D. Ruppe  
<destructionator gmail.com> wrote:

 Steven Schveighoffer:
 Are you doing anything with dynamic libraries?
None, except for the standard C library. It's pretty puzzling.
Considering that the functions work in some cases and not in others, it's probably a corruption issue. All I can say is, try to isolate *when* the corruption occurs. What I'd recommend is printing the contents of the typeinfo at the beginning of the program, then examine them after the corruption. See if you can spot a difference. I've done things like start a thread that continuously monitors a specific memory location to see if it ever changes, and then break on that check. Then look at the main thread to see what it is doing. These bugs suck, sorry you got one. -Steve
May 24 2011