Browse Source

Merge pull request #709 from svaarala/finalizer-torture-improvements

Forced stack reallocs in finalizer torture
pull/1454/head
Sami Vaarala 8 years ago
committed by GitHub
parent
commit
18ff0e4d4d
  1. 2
      RELEASES.rst
  2. 7
      src-input/duk_heap_finalize.c
  3. 6
      src-input/duk_hthread.h
  4. 89
      src-input/duk_hthread_stacks.c

2
RELEASES.rst

@ -2634,7 +2634,7 @@ Planned
(GH-1408)
* More assertion and torture test coverage for GC, finalizers, and error
handling (GH-1411, GH-1427)
handling (GH-1411, GH-1427, GH-709)
* Avoid relying on the value stack when handling a double error (error which
happened during handling of a previous error); this is cleaner but relying

7
src-input/duk_heap_finalize.c

@ -17,9 +17,12 @@ DUK_LOCAL duk_ret_t duk__fake_global_finalizer(duk_context *ctx) {
/* Require a lot of stack to force a value stack grow/shrink. */
duk_require_stack(ctx, 100000);
/* XXX: do something to force a callstack grow/shrink, perhaps
* just a manual forced resize or a forced relocating realloc?
/* Force a reallocation with pointer change for value, call, and
* catch stacks to maximize side effects.
*/
duk_hthread_valstack_torture_realloc((duk_hthread *) ctx);
duk_hthread_callstack_torture_realloc((duk_hthread *) ctx);
duk_hthread_catchstack_torture_realloc((duk_hthread *) ctx);
/* Inner function call, error throw. */
duk_eval_string_noresult(ctx,

6
src-input/duk_hthread.h

@ -386,6 +386,12 @@ DUK_INTERNAL_DECL void duk_hthread_catchstack_shrink_check(duk_hthread *thr);
DUK_INTERNAL_DECL void duk_hthread_catchstack_unwind_norz(duk_hthread *thr, duk_size_t new_top);
DUK_INTERNAL_DECL void duk_hthread_catchstack_unwind(duk_hthread *thr, duk_size_t new_top);
#if defined(DUK_USE_FINALIZER_TORTURE)
DUK_INTERNAL_DECL void duk_hthread_valstack_torture_realloc(duk_hthread *thr);
DUK_INTERNAL_DECL void duk_hthread_callstack_torture_realloc(duk_hthread *thr);
DUK_INTERNAL_DECL void duk_hthread_catchstack_torture_realloc(duk_hthread *thr);
#endif
DUK_INTERNAL_DECL void *duk_hthread_get_valstack_ptr(duk_heap *heap, void *ud); /* indirect allocs */
DUK_INTERNAL_DECL void *duk_hthread_get_callstack_ptr(duk_heap *heap, void *ud); /* indirect allocs */
DUK_INTERNAL_DECL void *duk_hthread_get_catchstack_ptr(duk_heap *heap, void *ud); /* indirect allocs */

89
src-input/duk_hthread_stacks.c

@ -490,3 +490,92 @@ DUK_INTERNAL void duk_hthread_catchstack_unwind(duk_hthread *thr, duk_size_t new
duk_hthread_catchstack_unwind_norz(thr, new_top);
DUK_REFZERO_CHECK_FAST(thr);
}
#if defined(DUK_USE_FINALIZER_TORTURE)
DUK_INTERNAL void duk_hthread_valstack_torture_realloc(duk_hthread *thr) {
duk_size_t alloc_size;
duk_tval *new_ptr;
duk_ptrdiff_t end_off;
duk_ptrdiff_t bottom_off;
duk_ptrdiff_t top_off;
if (thr->valstack == NULL) {
return;
}
end_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack);
bottom_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack);
top_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) thr->valstack);
alloc_size = (duk_size_t) end_off;
if (alloc_size == 0) {
return;
}
new_ptr = (duk_tval *) DUK_ALLOC(thr->heap, alloc_size);
if (new_ptr != NULL) {
DUK_MEMCPY((void *) new_ptr, (const void *) thr->valstack, alloc_size);
DUK_MEMSET((void *) thr->valstack, 0x55, alloc_size);
DUK_FREE(thr->heap, (void *) thr->valstack);
thr->valstack = new_ptr;
thr->valstack_end = (duk_tval *) ((duk_uint8_t *) new_ptr + end_off);
thr->valstack_bottom = (duk_tval *) ((duk_uint8_t *) new_ptr + bottom_off);
thr->valstack_top = (duk_tval *) ((duk_uint8_t *) new_ptr + top_off);
/* No change in size. */
} else {
DUK_D(DUK_DPRINT("failed to realloc valstack for torture, ignore"));
}
}
DUK_INTERNAL void duk_hthread_callstack_torture_realloc(duk_hthread *thr) {
duk_size_t alloc_size;
duk_activation *new_ptr;
duk_ptrdiff_t curr_off;
if (thr->callstack == NULL) {
return;
}
curr_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->callstack_curr - (duk_uint8_t *) thr->callstack);
alloc_size = sizeof(duk_activation) * thr->callstack_size;
if (alloc_size == 0) {
return;
}
new_ptr = (duk_activation *) DUK_ALLOC(thr->heap, alloc_size);
if (new_ptr != NULL) {
DUK_MEMCPY((void *) new_ptr, (const void *) thr->callstack, alloc_size);
DUK_MEMSET((void *) thr->callstack, 0x55, alloc_size);
DUK_FREE(thr->heap, (void *) thr->callstack);
thr->callstack = new_ptr;
thr->callstack_curr = (duk_activation *) ((duk_uint8_t *) new_ptr + curr_off);
/* No change in size. */
} else {
DUK_D(DUK_DPRINT("failed to realloc callstack for torture, ignore"));
}
}
DUK_INTERNAL void duk_hthread_catchstack_torture_realloc(duk_hthread *thr) {
duk_size_t alloc_size;
duk_catcher *new_ptr;
if (thr->catchstack == NULL) {
return;
}
alloc_size = sizeof(duk_catcher) * thr->catchstack_size;
if (alloc_size == 0) {
return;
}
new_ptr = (duk_catcher *) DUK_ALLOC(thr->heap, alloc_size);
if (new_ptr != NULL) {
DUK_MEMCPY((void *) new_ptr, (const void *) thr->catchstack, alloc_size);
DUK_MEMSET((void *) thr->catchstack, 0x55, alloc_size);
DUK_FREE(thr->heap, (void *) thr->catchstack);
thr->catchstack = new_ptr;
/* No change in size. */
} else {
DUK_D(DUK_DPRINT("failed to realloc catchstack for torture, ignore"));
}
}
#endif /* DUK_USE_FINALIZER_TORTURE */

Loading…
Cancel
Save