Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
Merge pull request #16 from CyberShadow/master
Browse files Browse the repository at this point in the history
Forbid interacting with the GC while a collection is in progress, to avoid memory corruption (issue 5653)
  • Loading branch information
andralex committed May 28, 2011
2 parents 2cd59c4 + 9c5ce2f commit 0a18e49
Showing 1 changed file with 22 additions and 0 deletions.
22 changes: 22 additions & 0 deletions src/gc/gcx.d
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,9 @@ class GC
assert(gcx);
//debug(PRINTF) printf("gcx.self = %x, pthread_self() = %x\n", gcx.self, pthread_self());

if (gcx.running)
onOutOfMemoryError();

size += SENTINEL_EXTRA;
bin = gcx.findBin(size);
Pool *pool;
Expand Down Expand Up @@ -582,6 +585,9 @@ class GC
//
private void *reallocNoSync(void *p, size_t size, uint bits = 0, size_t *alloc_size = null)
{
if (gcx.running)
onOutOfMemoryError();

if (!size)
{ if (p)
{ freeNoSync(p);
Expand Down Expand Up @@ -760,6 +766,9 @@ class GC
}
body
{
if (gcx.running)
onOutOfMemoryError();

//debug(PRINTF) printf("GC::extend(p = %p, minsize = %zu, maxsize = %zu)\n", p, minsize, maxsize);
version (SENTINEL)
{
Expand Down Expand Up @@ -848,6 +857,9 @@ class GC
assert(size != 0);
assert(gcx);

if (gcx.running)
onOutOfMemoryError();

return gcx.reserve(size);
}

Expand Down Expand Up @@ -881,6 +893,9 @@ class GC
debug(PRINTF) printf("Freeing %p\n", cast(size_t) p);
assert (p);

if (gcx.running)
onOutOfMemoryError();

Pool* pool;
size_t pagenum;
Bins bin;
Expand Down Expand Up @@ -1486,6 +1501,7 @@ struct Gcx
uint anychanges;
void *stackBottom;
uint inited;
uint running;
int disabled; // turn off collections if >0

byte *minAddr; // min(baseAddr)
Expand Down Expand Up @@ -2432,6 +2448,10 @@ struct Gcx
debug(COLLECT_PRINTF) printf("Gcx.fullcollect()\n");
//printf("\tpool address range = %p .. %p\n", minAddr, maxAddr);

if (running)
onOutOfMemoryError();
running = 1;

thread_suspendAll();

cached_size_key = cached_size_key.init;
Expand Down Expand Up @@ -2779,6 +2799,8 @@ struct Gcx
debug(COLLECT_PRINTF) printf("\trecovered pages = %d\n", recoveredpages);
debug(COLLECT_PRINTF) printf("\tfree'd %u bytes, %u pages from %u pools\n", freed, freedpages, npools);

running = 0; // only clear on success

return freedpages + recoveredpages;
}

Expand Down

2 comments on commit 0a18e49

@MartinNowak
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this please be something but an OutOfMemory exception. Clearly if interacting with the GC in finalizers in disallowed this is
a programming error and rather calls for a hlt instruction or should at least carry a specific message.

@complexmath
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What should probably happen is for allocations during the finalization phase of a collection to simply get more memory from the OS if there isn't enough available--ie. pretend that GC.disable() is set.

Please sign in to comment.