Jump to page: 1 2
Thread overview
DMD optimization bug?
Mar 21, 2013
Jacob Carlborg
Mar 21, 2013
Iain Buclaw
Mar 22, 2013
Jacob Carlborg
Mar 22, 2013
Dmitry Olshansky
Mar 22, 2013
Jacob Carlborg
Mar 22, 2013
Dmitry Olshansky
Mar 22, 2013
Jacob Carlborg
Mar 22, 2013
Dmitry Olshansky
Mar 22, 2013
Jacob Carlborg
Mar 22, 2013
Dmitry Olshansky
Mar 22, 2013
Jacob Carlborg
Mar 21, 2013
Iain Buclaw
March 21, 2013
The code below works fine without optimizations. But with optimizations (the -O flag) turned on it segfaults. The behavior with optimizations turned on is a bit different depending on which version of DMD I try and if I compile for 32 or 64bit.

DMD 2.062 64bit: Segfault
DMD 2.062 32bit: Prints a huge array then segfault
DMD 2.061 64bit: Segfault
DMD 2.061 32bit: Prints a fairly small array (10 elements) with random numbers
DMD head (7dcc72a997) 32bit: Bus error: 10

I'm using Mac OS X 10.8.2.

import std.stdio;

int[]* getDeserializedSlice ()
{
    void[] a = [1, 2, 3, 4, 5].dup;
    auto b = &a;

    if (auto c = b)
        auto d = &(cast(int[]) *c)[1 .. 1 + 2];

    return null;
}

void main ()
{
    writeln(*getDeserializedSlice());
}

Is the above code supposed to work? The test case might look a bit strange, the full source code is here:

https://github.com/jacob-carlborg/orange/blob/master/orange/serialization/Serializer.d#L1672

-- 
/Jacob Carlborg
March 21, 2013
On 21 March 2013 20:29, Jacob Carlborg <doob@me.com> wrote:

> The code below works fine without optimizations. But with optimizations (the -O flag) turned on it segfaults. The behavior with optimizations turned on is a bit different depending on which version of DMD I try and if I compile for 32 or 64bit.
>
> DMD 2.062 64bit: Segfault
> DMD 2.062 32bit: Prints a huge array then segfault
> DMD 2.061 64bit: Segfault
> DMD 2.061 32bit: Prints a fairly small array (10 elements) with random
> numbers
> DMD head (7dcc72a997) 32bit: Bus error: 10
>
> I'm using Mac OS X 10.8.2.
>
> import std.stdio;
>
> int[]* getDeserializedSlice ()
> {
>     void[] a = [1, 2, 3, 4, 5].dup;
>     auto b = &a;
>
>     if (auto c = b)
>         auto d = &(cast(int[]) *c)[1 .. 1 + 2];
>
>     return null;
> }
>
> void main ()
> {
>     writeln(*getDeserializedSlice(**));
> }
>
> Is the above code supposed to work? The test case might look a bit strange, the full source code is here:
>
> https://github.com/jacob-**carlborg/orange/blob/master/** orange/serialization/**Serializer.d#L1672<https://github.com/jacob-carlborg/orange/blob/master/orange/serialization/Serializer.d#L1672>
>
> --
> /Jacob Carlborg
>


As I see it, that code should *always* cause a segmentation fault.

You are returning 'null', and then dereferencing it...


Regards
-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';


March 21, 2013
On 21 March 2013 21:46, Iain Buclaw <ibuclaw@ubuntu.com> wrote:

>
> On 21 March 2013 20:29, Jacob Carlborg <doob@me.com> wrote:
>
>> The code below works fine without optimizations. But with optimizations (the -O flag) turned on it segfaults. The behavior with optimizations turned on is a bit different depending on which version of DMD I try and if I compile for 32 or 64bit.
>>
>> DMD 2.062 64bit: Segfault
>> DMD 2.062 32bit: Prints a huge array then segfault
>> DMD 2.061 64bit: Segfault
>> DMD 2.061 32bit: Prints a fairly small array (10 elements) with random
>> numbers
>> DMD head (7dcc72a997) 32bit: Bus error: 10
>>
>> I'm using Mac OS X 10.8.2.
>>
>> import std.stdio;
>>
>> int[]* getDeserializedSlice ()
>> {
>>     void[] a = [1, 2, 3, 4, 5].dup;
>>     auto b = &a;
>>
>>     if (auto c = b)
>>         auto d = &(cast(int[]) *c)[1 .. 1 + 2];
>>
>>     return null;
>> }
>>
>> void main ()
>> {
>>     writeln(*getDeserializedSlice());
>> }
>>>
>>>
>>
>> Is the above code supposed to work? The test case might look a bit strange, the full source code is here:
>>
>>
>> https://github.com/jacob-carlborg/orange/blob/master/orange/serialization/Serializer.d#L1672
>>
>> --
>> /Jacob Carlborg
>>
>
>
> As I see it, that code should *always* cause a segmentation fault.
>
> You are returning 'null', and then dereferencing it...
>
>
Just to be clear, the program should stop at the point of:

writeln(*getDeserializedSlice())

Where getSerializedSlice() has returned 'null' and then null gets
dereferenced.  All other behaviours where the program tries to print
*(null) are wrong code.


-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';


March 22, 2013
On 2013-03-21 22:46, Iain Buclaw wrote:
> On 21 March 2013 20:29, Jacob Carlborg <doob@me.com
> <mailto:doob@me.com>> wrote:
>
>     The code below works fine without optimizations. But with
>     optimizations (the -O flag) turned on it segfaults. The behavior
>     with optimizations turned on is a bit different depending on which
>     version of DMD I try and if I compile for 32 or 64bit.
>
>     DMD 2.062 64bit: Segfault
>     DMD 2.062 32bit: Prints a huge array then segfault
>     DMD 2.061 64bit: Segfault
>     DMD 2.061 32bit: Prints a fairly small array (10 elements) with
>     random numbers
>     DMD head (7dcc72a997) 32bit: Bus error: 10
>
>     I'm using Mac OS X 10.8.2.
>
>     import std.stdio;
>
>     int[]* getDeserializedSlice ()
>     {
>          void[] a = [1, 2, 3, 4, 5].dup;
>          auto b = &a;
>
>          if (auto c = b)
>              auto d = &(cast(int[]) *c)[1 .. 1 + 2];
>
>          return null;
>     }
>
>     void main ()
>     {
>          writeln(*getDeserializedSlice(__));
>     }
>
>     Is the above code supposed to work? The test case might look a bit
>     strange, the full source code is here:
>
>     https://github.com/jacob-__carlborg/orange/blob/master/__orange/serialization/__Serializer.d#L1672
>     <https://github.com/jacob-carlborg/orange/blob/master/orange/serialization/Serializer.d#L1672>
>
>     --
>     /Jacob Carlborg

Crap, that example was incorrect, it should look like this:

return &(cast(int[]) *c)[1 .. 1 + 2];

-- 
/Jacob Carlborg
March 22, 2013
22-Mar-2013 11:26, Jacob Carlborg пишет:
> On 2013-03-21 22:46, Iain Buclaw wrote:
>> On 21 March 2013 20:29, Jacob Carlborg <doob@me.com
>> <mailto:doob@me.com>> wrote:
>>
>>     The code below works fine without optimizations. But with
>>     optimizations (the -O flag) turned on it segfaults. The behavior
>>     with optimizations turned on is a bit different depending on which
>>     version of DMD I try and if I compile for 32 or 64bit.
>>
>>     DMD 2.062 64bit: Segfault
>>     DMD 2.062 32bit: Prints a huge array then segfault
>>     DMD 2.061 64bit: Segfault
>>     DMD 2.061 32bit: Prints a fairly small array (10 elements) with
>>     random numbers
>>     DMD head (7dcc72a997) 32bit: Bus error: 10
>>
>>     I'm using Mac OS X 10.8.2.
>>
>>     import std.stdio;
>>
>>     int[]* getDeserializedSlice ()
>>     {
>>          void[] a = [1, 2, 3, 4, 5].dup;
>>          auto b = &a;
>>
>>          if (auto c = b)
>>              auto d = &(cast(int[]) *c)[1 .. 1 + 2];
>>
>>          return null;
>>     }
>>
>>     void main ()
>>     {
>>          writeln(*getDeserializedSlice(__));
>>     }
>>
>>     Is the above code supposed to work? The test case might look a bit
>>     strange, the full source code is here:
>>
>>
>> https://github.com/jacob-__carlborg/orange/blob/master/__orange/serialization/__Serializer.d#L1672
>>
>>
>> <https://github.com/jacob-carlborg/orange/blob/master/orange/serialization/Serializer.d#L1672>
>>
>>
>>     --
>>     /Jacob Carlborg
>
> Crap, that example was incorrect, it should look like this:
>
> return &(cast(int[]) *c)[1 .. 1 + 2];

OK so c points to [1, 2, 3, 4, 5] (and who knows if it's 5 bytes or 5 ints) slice. *c is that slice, (cast(int[])*c)[1..3] is pieces of that slice an r-value.
Mmm so you are returning a pointer to r-value (a local temporary)? What's the point of the code?

-- 
Dmitry Olshansky
March 22, 2013
On 2013-03-22 09:14, Dmitry Olshansky wrote:

> OK so c points to [1, 2, 3, 4, 5] (and who knows if it's 5 bytes or 5
> ints) slice. *c is that slice, (cast(int[])*c)[1..3] is pieces of that
> slice an r-value.
> Mmm so you are returning a pointer to r-value (a local temporary)?
> What's the point of the code?

I'm showing here a reduced minimal test case, that's why it looks strange. The full source code is here:

https://github.com/jacob-carlborg/orange/blob/master/orange/serialization/Serializer.d#L1672

private T* getDeserializedSlice (T) (Slice slice)
{
    if (auto array = slice.id in deserializedSlices)
        return &(cast(T) *array)[slice.offset .. slice.offset + slice.length];

    return null;
}

In my serializer I'm storing already deserialized arrays in a associative array, looking like this:

void[][size_t] deserializedSlices;

The "size_t" is a unique identification. What I'm doing here is returning a slice from an already deserialized array. "Slice" is a struct as follows:

struct Slice
{
    size_t id; // id of the array the slice originates to
    size_t offset; // start position of the slice in the array
    size_t length; // length of the slice
}

What I'm doing in "getDeserializedSlice" is checking if the slice id is available in the associative array. If it is I deference the array (since I'm getting a pointer from the "in" expression), then casting it to the correct array type. After that I'm slicing the array and returns a pointer to it. I figured that was safe since it's always stored in the associative array, but that might not be the case.

I guess I could return the slice by an out parameter instead and return a bool from the function.

-- 
/Jacob Carlborg
March 22, 2013
22-Mar-2013 13:01, Jacob Carlborg пишет:
> On 2013-03-22 09:14, Dmitry Olshansky wrote:
>
>> OK so c points to [1, 2, 3, 4, 5] (and who knows if it's 5 bytes or 5
>> ints) slice. *c is that slice, (cast(int[])*c)[1..3] is pieces of that
>> slice an r-value.
>> Mmm so you are returning a pointer to r-value (a local temporary)?
>> What's the point of the code?
>
> I'm showing here a reduced minimal test case, that's why it looks
> strange. The full source code is here:
>

It doesn't change the fact that pointer to slice is not going to work. Esp pointer to stack-allocated slice. You'll get garbage and sometimes segfaults.

What's wrong with returning slice by value ?

> https://github.com/jacob-carlborg/orange/blob/master/orange/serialization/Serializer.d#L1672
>
Exactly what you describe there is not going to work at all. Taking address of temporary slice (a[x..y] is a temporary value) is welcoming a segfault.



-- 
Dmitry Olshansky
March 22, 2013
On 2013-03-22 10:07, Dmitry Olshansky wrote:

> What's wrong with returning slice by value ?

I want to know both if it exists and get back the value. I could use an out parameter for that though.

-- 
/Jacob Carlborg
March 22, 2013
22-Mar-2013 15:56, Jacob Carlborg пишет:
> On 2013-03-22 10:07, Dmitry Olshansky wrote:
>
>> What's wrong with returning slice by value ?
>
> I want to know both if it exists and get back the value. I could use an
> out parameter for that though.
>

Yes, that or ref parameter.

Another option is:

return null - doesn't exists (both ptr and .length are zeros)

return a slice that has zero length and non-zero ptr - exists but empty

Dunno if it's suitable to what your doing with it later on.

-- 
Dmitry Olshansky
March 22, 2013
On 2013-03-22 13:00, Dmitry Olshansky wrote:

> Yes, that or ref parameter.
>
> Another option is:
>
> return null - doesn't exists (both ptr and .length are zeros)
>
> return a slice that has zero length and non-zero ptr - exists but empty
>
> Dunno if it's suitable to what your doing with it later on.

Yeah, that would probably also work. Thanks for the help.

BTW, was it only luck that it worked with out optimizations?

-- 
/Jacob Carlborg
« First   ‹ Prev
1 2