Thread overview | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
March 21, 2013 DMD optimization bug? | ||||
---|---|---|---|---|
| ||||
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 Re: DMD optimization bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg Attachments:
| 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 Re: DMD optimization bug? | ||||
---|---|---|---|---|
| ||||
Attachments:
| 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 Re: DMD optimization bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Iain Buclaw | 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 Re: DMD optimization bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | 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 Re: DMD optimization bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dmitry Olshansky | 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 Re: DMD optimization bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | 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 Re: DMD optimization bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dmitry Olshansky | 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 Re: DMD optimization bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | 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 Re: DMD optimization bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dmitry Olshansky | 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 |
Copyright © 1999-2021 by the D Language Foundation