+2009-09-10 Ivan Maidanski <ivmai@mail.ru>
+ (diff117)
+
+ * dbg_mlc.c (OFN_UNSET): New macro (to detect
+ GC_register_finalizer() failures).
+ * dbg_mlc.c (store_old): Add a check for register_finalizer()
+ failure caused by an out-of-memory event (leave *ofn and *ocd
+ unmodified in that case).
+ * dbg_mlc.c (GC_debug_register_finalizer,
+ GC_debug_register_finalizer_no_order,
+ GC_debug_register_finalizer_unreachable,
+ GC_debug_register_finalizer_ignore_self): Initialize my_old_fn
+ to OFN_UNSET; clear *ocd and *ofn for non-heap objects (the same
+ as in GC_register_finalizer_inner()).
+
2009-09-10 Ivan Maidanski <ivmai@mail.ru>
(diff116a, diff116b, diff116c)
(*(cl -> cl_fn))((void *)((char *)obj + sizeof(oh)), cl -> cl_data);
}
+/* Special finalizer_proc value to detect GC_register_finalizer() failure. */
+#define OFN_UNSET (GC_finalization_proc)(signed_word)-1
+
/* Set ofn and ocd to reflect the values we got back. */
static void store_old (void *obj, GC_finalization_proc my_old_fn,
struct closure *my_old_cd, GC_finalization_proc *ofn,
void **ocd)
{
if (0 != my_old_fn) {
+ if (my_old_fn == OFN_UNSET) {
+ /* register_finalizer() failed; (*ofn) and (*ocd) are unchanged. */
+ return;
+ }
if (my_old_fn != GC_debug_invoke_finalizer) {
GC_err_printf("Debuggable object at %p had non-debug finalizer.\n",
obj);
void * cd, GC_finalization_proc *ofn,
void * *ocd)
{
- GC_finalization_proc my_old_fn;
+ GC_finalization_proc my_old_fn = OFN_UNSET;
void * my_old_cd;
ptr_t base = GC_base(obj);
- if (0 == base) return;
+ if (0 == base) {
+ /* We won't collect it, hence finalizer wouldn't be run. */
+ if (ocd) *ocd = 0;
+ if (ofn) *ofn = 0;
+ return;
+ }
if ((ptr_t)obj - base != sizeof(oh)) {
GC_err_printf(
"GC_debug_register_finalizer called with non-base-pointer %p\n",
void * cd, GC_finalization_proc *ofn,
void * *ocd)
{
- GC_finalization_proc my_old_fn;
+ GC_finalization_proc my_old_fn = OFN_UNSET;
void * my_old_cd;
ptr_t base = GC_base(obj);
- if (0 == base) return;
+ if (0 == base) {
+ /* We won't collect it, hence finalizer wouldn't be run. */
+ if (ocd) *ocd = 0;
+ if (ofn) *ofn = 0;
+ return;
+ }
if ((ptr_t)obj - base != sizeof(oh)) {
GC_err_printf(
"GC_debug_register_finalizer_no_order called with "
void * cd, GC_finalization_proc *ofn,
void * *ocd)
{
- GC_finalization_proc my_old_fn;
+ GC_finalization_proc my_old_fn = OFN_UNSET;
void * my_old_cd;
ptr_t base = GC_base(obj);
- if (0 == base) return;
+ if (0 == base) {
+ /* We won't collect it, hence finalizer wouldn't be run. */
+ if (ocd) *ocd = 0;
+ if (ofn) *ofn = 0;
+ return;
+ }
if ((ptr_t)obj - base != sizeof(oh)) {
GC_err_printf(
"GC_debug_register_finalizer_unreachable called with "
void * cd, GC_finalization_proc *ofn,
void * *ocd)
{
- GC_finalization_proc my_old_fn;
+ GC_finalization_proc my_old_fn = OFN_UNSET;
void * my_old_cd;
ptr_t base = GC_base(obj);
- if (0 == base) return;
+ if (0 == base) {
+ /* We won't collect it, hence finalizer wouldn't be run. */
+ if (ocd) *ocd = 0;
+ if (ofn) *ofn = 0;
+ return;
+ }
if ((ptr_t)obj - base != sizeof(oh)) {
GC_err_printf(
"GC_debug_register_finalizer_ignore_self called with "