vmware-archive / go-pmem-transaction

Golang library for using persistent memory
Other
29 stars 5 forks source link

apiCrash* functions do not work well with GC #3

Open jerrinsg opened 5 years ago

jerrinsg commented 5 years ago

The test framework does a cmd.Run() to run apiCrash* functions in a child process. These child processes create heap objects in persistent memory and make these new objects visible in the parent process by linking it to the application root pointer. But this violates the assumptions of the parent process's garbage collector. On its next full cycle, the GC finds new objects reachable from the application root pointer that was not allocated in its lifetime and causes the program to crash.

mohit10verma commented 5 years ago

Hi Jerrin, Can you tell me more about the assumption of the parent process's garbage collector? Shouldn't a child process be able to attach a new object to the root pointer so the parent can access it later?

jerrinsg commented 5 years ago

Each Go process maintains in the runtime some state information regarding memory allocation and garbage collection - the current number of live persistent memory objects (say nlive), the number of persistent memory objects freed up in the last garbage collection cycle (say nfreed), etc. These stats are maintained in volatile memory.

Whenever the memory allocator allocates an object in the heap, it increments nlive. And, when a garbage collection cycle is run, the GC decrements nlive depending on how many objects it freed up. So running a GC cycle will never result in the value of nlive getting incremented.

When a parent process P forks a child process C, each process has its own accounting of the number of live objects - say nliveP and nliveC. When C creates two new persistent memory objects, C's runtime increments the value of nliveC. By adding pointers to these objects in the application root pointer, they are also made visible in the parent process. But when P runs its next GC cycle, it sees that the actual number of live objects is greater than nliveP which violates the assumptions of the garbage collector.