Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
December 13, 2014 Segmentation fault after having a certain number of elements in an array? | ||||
---|---|---|---|---|
| ||||
I'll be trying to narrow it down even more tomorrow, but I was hoping somone here might have some insight into this weird issue I am having. I have a dynamic array of shorts that I had been trying to append to (capturing sound data). I kept getting a segfault when doing the append, and have narrowed it down to getting a segfault when the length of the array is equal to or greater than 1024. It looks wonky because of my many tests, but this is the code that was causing the segfault: override bool onProcessSamples(const(short)[] samples) { import std.stdio; for(int i = 0; i<samples.length; ++i) { writeln(m_samples.length); m_samples.length +=1; } return true; } It will print all the numbers, endikng with 1023, and then it shows "Segmentation fault" and if I comment out the writeln line it just shows the Segmentation fault line. Similar code that would cause the length to be at 1024 or higher will also cause a segfault. The class that this method belongs to is wraped up in a C++ interface and it gets called C++ side. Also, if I set the length to 1024 or higher in the class constructor or if I create a different array elsewhere and set its length to 1024 or higher, I don't get the segfault anymore. As far as I can tell, this only happens because it is called in C++ code. It doesn't appear to happen on my system at all if I do anything like this outside of my C++ interoperating. So far my fix is to set the length of the array to 1024, and then right away set it back to 0 in the class' constructor, but I'd like to get this to work without any strange hacks. |
December 13, 2014 Re: Segmentation fault after having a certain number of elements in an array? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jeremy DeHaan | I should also mention that this is on Linux. I haven't tried on OSX or Windows yet. |
December 13, 2014 Re: Segmentation fault after having a certain number of elements in an array? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jeremy DeHaan | On Saturday, 13 December 2014 at 08:59:19 UTC, Jeremy DeHaan wrote: > for(int i = 0; i<samples.length; ++i) > m_samples.length +=1; You are testing i against an ever-increasing limit aren't you, so it's an infinite loop. |
December 13, 2014 Re: Segmentation fault after having a certain number of elements in an array? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paul | On Saturday, 13 December 2014 at 09:24:51 UTC, Paul wrote:
> You are testing i against an ever-increasing limit aren't you, so it's an infinite loop.
Read more carefully. samples is unmodified, it's m_samples whose length is changed.
|
December 13, 2014 Re: Segmentation fault after having a certain number of elements in an array? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paul | On Saturday, 13 December 2014 at 09:24:51 UTC, Paul wrote:
> On Saturday, 13 December 2014 at 08:59:19 UTC, Jeremy DeHaan wrote:
>
>
>> for(int i = 0; i<samples.length; ++i)
>
>> m_samples.length +=1;
>
> You are testing i against an ever-increasing limit aren't you, so it's an infinite loop.
Not really. When the function is called, the length of "samples" (Incoming sound data) is usually around 4000. "m_samples" (the total samples recorded) doesn't make it past 1024 in length without segfaulting.
It probably doesn't matter, but the array passed to this function is actually a slice created from a pointer and length generated in the C++ side.
|
December 13, 2014 Re: Segmentation fault after having a certain number of elements in an array? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jeremy DeHaan | On Saturday, 13 December 2014 at 08:59:19 UTC, Jeremy DeHaan wrote:
> I'll be trying to narrow it down even more tomorrow, but I was hoping somone here might have some insight into this weird issue I am having.
Could you upload the code to somewhere? With only a small snippet, it's hard to get any clue.
|
December 13, 2014 Re: Segmentation fault after having a certain number of elements in an array? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Artem Tarasov | On Saturday, 13 December 2014 at 09:47:40 UTC, Artem Tarasov wrote:
> On Saturday, 13 December 2014 at 08:59:19 UTC, Jeremy DeHaan wrote:
>> I'll be trying to narrow it down even more tomorrow, but I was hoping somone here might have some insight into this weird issue I am having.
>
> Could you upload the code to somewhere? With only a small snippet, it's hard to get any clue.
Yes, but it might take some time. I'll have to make a reduced c++ and D portion. I'll see what I can manage.
|
December 15, 2014 Re: Segmentation fault after having a certain number of elements in an array? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jeremy DeHaan | On 12/13/14 3:59 AM, Jeremy DeHaan wrote:
> I'll be trying to narrow it down even more tomorrow, but I was hoping
> somone here might have some insight into this weird issue I am having.
>
> I have a dynamic array of shorts that I had been trying to append to
> (capturing sound data). I kept getting a segfault when doing the append,
> and have narrowed it down to getting a segfault when the length of the
> array is equal to or greater than 1024.
>
> It looks wonky because of my many tests, but this is the code that was
> causing the segfault:
>
> override bool onProcessSamples(const(short)[] samples)
> {
> import std.stdio;
> for(int i = 0; i<samples.length; ++i)
> {
> writeln(m_samples.length);
> m_samples.length +=1;
> }
> return true;
> }
>
> It will print all the numbers, endikng with 1023, and then it shows
> "Segmentation fault" and if I comment out the writeln line it just shows
> the Segmentation fault line. Similar code that would cause the length to
> be at 1024 or higher will also cause a segfault.
>
> The class that this method belongs to is wraped up in a C++ interface
> and it gets called C++ side.
>
> Also, if I set the length to 1024 or higher in the class constructor or
> if I create a different array elsewhere and set its length to 1024 or
> higher, I don't get the segfault anymore.
>
> As far as I can tell, this only happens because it is called in C++
> code. It doesn't appear to happen on my system at all if I do anything
> like this outside of my C++ interoperating. So far my fix is to set the
> length of the array to 1024, and then right away set it back to 0 in the
> class' constructor, but I'd like to get this to work without any strange
> hacks.
A guess -- is the class instantiated in C++? if so, it probably is not on the D heap, and probably is not scanned during GC collections. I think your m_samples array is reallocated during a collection, and you are using dangling memory.
Try GC.addRoot(this) at the start of the function, and see if it helps.
-Steve
|
December 15, 2014 Re: Segmentation fault after having a certain number of elements in an array? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 12/15/14 10:24 AM, Steven Schveighoffer wrote: > > A guess -- is the class instantiated in C++? if so, it probably is not > on the D heap, and probably is not scanned during GC collections. I > think your m_samples array is reallocated during a collection, and you > are using dangling memory. > > Try GC.addRoot(this) at the start of the function, and see if it helps. Ugh... just after saying that, I realized this will not help, because the memory pointed at by 'this' is not GC allocated. You have to GC.addRoot the m_samples array data, but even when you do that, any time you append it may reallocate, so every time that happens, you must re-add the root. But you can add the range which includes the m_samples array pointer, and that should solve it (you must do this when m_samples is first allocated, i.e. when it starts pointing at GC memory). GC.addRange(&m_samples, sizeof(m_samples)); If that doesn't work, try this instead: override bool onProcessSamples(const(short)[] samples) { import std.stdio; import core.memory; auto tmpsamples = m_samples.ptr; for(int i = 0; i<samples.length; ++i) { writeln(m_samples.length); m_samples.length +=1; if(m_samples.ptr !is tmpsamples) // if pointer changed { GC.addRoot(m_samples.ptr); if(tmpsamples) GC.removeRoot(tmpsamples); tmpsamples = m_samples.ptr; } } return true; } -Steve |
Copyright © 1999-2021 by the D Language Foundation