Jump to page: 1 2
Thread overview
Garbage Collection Pitfall in C++ but not in D?
Jul 06, 2012
akaz
Jul 06, 2012
Denis Shelomovskij
Jul 06, 2012
akaz
Jul 06, 2012
Timon Gehr
Jul 06, 2012
akaz
Jul 06, 2012
Simon
Jul 07, 2012
akaz
Jul 07, 2012
akaz
Jul 07, 2012
David Nadlinger
July 06, 2012
Hi,

 Reading about the C++11, I stumbled upon this:

 http://www2.research.att.com/~bs/C++0xFAQ.html#gc-abi

 Specifically (quote):

 	int* p = new int;
	p+=10;
	// ... collector may run here ...
	p-=10;
	*p = 10;	// can we be sure that the int is still there?

 How does the D garbage collector solves (answers) that?

Thank you.
July 06, 2012
06.07.2012 17:43, akaz пишет:
> Hi,
>
>   Reading about the C++11, I stumbled upon this:
>
>   http://www2.research.att.com/~bs/C++0xFAQ.html#gc-abi
>
>   Specifically (quote):
>
>       int* p = new int;
>      p+=10;
>      // ... collector may run here ...
>      p-=10;
>      *p = 10;    // can we be sure that the int is still there?
>
>   How does the D garbage collector solves (answers) that?
>
> Thank you.

If you are interested in D read this first:
http://dlang.org/garbage.html

You can find there e.g.:
> Do not add or subtract an offset to a pointer such that the result points outside of the bounds of the garbage collected object originally allocated.

So `p+=10;` is already "undefined behavior".

-- 
Денис В. Шеломовский
Denis V. Shelomovskij


July 06, 2012
>
> If you are interested in D read this first:
> http://dlang.org/garbage.html
>
> You can find there e.g.:
> > Do not add or subtract an offset to a pointer such that the
> result points outside of the bounds of the garbage collected object originally allocated.
>
> So `p+=10;` is already "undefined behavior".

Thank you, this clear the issue.



July 06, 2012
On 06-07-2012 16:07, Denis Shelomovskij wrote:
> 06.07.2012 17:43, akaz пишет:
>> Hi,
>>
>> Reading about the C++11, I stumbled upon this:
>>
>> http://www2.research.att.com/~bs/C++0xFAQ.html#gc-abi
>>
>> Specifically (quote):
>>
>> int* p = new int;
>> p+=10;
>> // ... collector may run here ...
>> p-=10;
>> *p = 10; // can we be sure that the int is still there?
>>
>> How does the D garbage collector solves (answers) that?
>>
>> Thank you.
>
> If you are interested in D read this first:
> http://dlang.org/garbage.html
>
> You can find there e.g.:
>  > Do not add or subtract an offset to a pointer such that the result
> points outside of the bounds of the garbage collected object originally
> allocated.
>
> So `p+=10;` is already "undefined behavior".
>

I'll just add: Handling this case is basically impossible to do sanely. You can't really know what some pointer off the bounds of a managed memory region is based on. It could literally be based on any memory region in the entire program. You could do heuristics of course, but . . .

-- 
Alex Rønne Petersen
alex@lycus.org
http://lycus.org
July 06, 2012
On 07/06/2012 05:39 PM, Alex Rønne Petersen wrote:
> On 06-07-2012 16:07, Denis Shelomovskij wrote:
>> 06.07.2012 17:43, akaz пишет:
>>> Hi,
>>>
>>> Reading about the C++11, I stumbled upon this:
>>>
>>> http://www2.research.att.com/~bs/C++0xFAQ.html#gc-abi
>>>
>>> Specifically (quote):
>>>
>>> int* p = new int;
>>> p+=10;
>>> // ... collector may run here ...
>>> p-=10;
>>> *p = 10; // can we be sure that the int is still there?
>>>
>>> How does the D garbage collector solves (answers) that?
>>>
>>> Thank you.
>>
>> If you are interested in D read this first:
>> http://dlang.org/garbage.html
>>
>> You can find there e.g.:
>> > Do not add or subtract an offset to a pointer such that the result
>> points outside of the bounds of the garbage collected object originally
>> allocated.
>>
>> So `p+=10;` is already "undefined behavior".
>>
>
> I'll just add: Handling this case is basically impossible to do sanely.
> You can't really know what some pointer off the bounds of a managed
> memory region is based on. It could literally be based on any memory
> region in the entire program. You could do heuristics of course, but . . .
>

You could run the program in a dedicated VM. :)
July 06, 2012
On Friday, 6 July 2012 at 15:39:40 UTC, Alex Rønne Petersen wrote:
> On 06-07-2012 16:07, Denis Shelomovskij wrote:
>> 06.07.2012 17:43, akaz пишет:
>>> Hi,
>>>
>>> Reading about the C++11, I stumbled upon this:
>>>
>
> I'll just add: Handling this case is basically impossible to do sanely. You can't really know what some pointer off the bounds of a managed memory region is based on. It could literally be based on any memory region in the entire program. You could do heuristics of course, but . . .

Is not possible to make use of addRange() and removeRange() to "block" the GC over a specified time/range?
July 06, 2012
On 06-07-2012 22:07, akaz wrote:
> On Friday, 6 July 2012 at 15:39:40 UTC, Alex Rønne Petersen wrote:
>> On 06-07-2012 16:07, Denis Shelomovskij wrote:
>>> 06.07.2012 17:43, akaz пишет:
>>>> Hi,
>>>>
>>>> Reading about the C++11, I stumbled upon this:
>>>>
>>
>> I'll just add: Handling this case is basically impossible to do
>> sanely. You can't really know what some pointer off the bounds of a
>> managed memory region is based on. It could literally be based on any
>> memory region in the entire program. You could do heuristics of
>> course, but . . .
>
> Is not possible to make use of addRange() and removeRange() to "block"
> the GC over a specified time/range?

Those just add root ranges, i.e. areas of memory that will be scanned for [interior] pointers during the marking phase. It still won't solve the problem.

You can disable the GC entirely with GC.disable().

-- 
Alex Rønne Petersen
alex@lycus.org
http://lycus.org


July 06, 2012
On 06/07/2012 16:39, Alex Rønne Petersen wrote:
> On 06-07-2012 16:07, Denis Shelomovskij wrote:
>> 06.07.2012 17:43, akaz пишет:
>>> Hi,
>>>
>>> Reading about the C++11, I stumbled upon this:
>>>
>>> http://www2.research.att.com/~bs/C++0xFAQ.html#gc-abi
>>>
>>> Specifically (quote):
>>>
>>> int* p = new int;
>>> p+=10;
>>> // ... collector may run here ...
>>> p-=10;
>>> *p = 10; // can we be sure that the int is still there?
>>>
>>> How does the D garbage collector solves (answers) that?
>>>
>>> Thank you.
>>
>> If you are interested in D read this first:
>> http://dlang.org/garbage.html
>>
>> You can find there e.g.:
>>  > Do not add or subtract an offset to a pointer such that the result
>> points outside of the bounds of the garbage collected object originally
>> allocated.
>>
>> So `p+=10;` is already "undefined behavior".
>>
>
> I'll just add: Handling this case is basically impossible to do sanely.
> You can't really know what some pointer off the bounds of a managed
> memory region is based on. It could literally be based on any memory
> region in the entire program. You could do heuristics of course, but . . .
>

Never mind what D says, even in C/C++ just doing the p += 10 is invalid.

Creating a pointer that points at invalid memory is just as wrong as dereferencing it would be. The possible crash on the dereference of the pointer is just the symptom of the under lying bug.

With visual studio & their implementation of the std containers, in a debug build if you increment/decrement or otherwise create an iterator that's outside the allowable bounds of the container you get a runtime assertion failure.

It's a very handy feature and uncovered a load of bugs when we upgraded to VS 2008.

-- 
My enormous talent is exceeded only by my outrageous laziness.
http://www.ssTk.co.uk


July 07, 2012
On Friday, 6 July 2012 at 21:10:56 UTC, Simon wrote:
> On 06/07/2012 16:39, Alex Rønne Petersen wrote:
>> On 06-07-2012 16:07, Denis Shelomovskij wrote:
>>> 06.07.2012 17:43, akaz пишет:
>
> Never mind what D says, even in C/C++ just doing the p += 10 is invalid.
>
> Creating a pointer that points at invalid memory is just as wrong as dereferencing it would be.

Actually, p+10 could still be valid memory.

OTOH, the other case that's given on the original page is this one:

	int* p = new int;
	int x = reinterpret_cast<int>(p);	// non-portable
	p=0;
	// ... collector may run here ...
	p = reinterpret_cast<int*>(x);
	*p = 10;	// can we be sure that the int is still there?

So, the pointer could sometimes simply disappear temporarily, without becoming invalid (well, p==NULL is somewhat invalid, bt it could have been p=&q). Just some allocated memory is no longer referenced for the time being and this could trigger the GC without protection (except disabling GC for the entire application).

Won't some functions doing just what addRange() and removeRange() do solve that kind of problem (if necessary)? That means, forbidding the GC to scan some memory area for some time?
July 07, 2012
> Won't some functions doing just what addRange() and removeRange() do solve that kind of problem (if necessary)? That means, forbidding the GC to scan some memory area for some time?

Like their C++11 counterparts:

	void declare_reachable(void* p);	// the region of memory starting at p
						// (and allocated by some allocator
						// operation which remembers its size)
						// must not be collected
	template<class T> T* undeclare_reachable(T* p);

	void declare_no_pointers(char* p, size_t n);	   // p[0..n] holds no pointers
	void undeclare_no_pointers(char* p, size_t n);


« First   ‹ Prev
1 2