View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0000412 | LDMud 3.3 | Efuns | public | 2005-11-07 17:37 | 2018-01-29 21:57 |
Reporter | Gnomi | Assigned To | |||
Priority | normal | Severity | minor | Reproducibility | always |
Status | closed | Resolution | fixed | ||
Platform | i686 | OS | Debian GNU/Linux | OS Version | 3.1 |
Product Version | 3.3 | ||||
Fixed in Version | 3.3 | ||||
Summary | 0000412: symbol_function leaks an object reference | ||||
Description | Hi, the following object stays with two references in the destructed object list (one reference for the list, one leaked): void create() { closure cl = symbol_function("create", this_object()); destruct(this_object()); } That's because symbol_function doesn't release the reference for the object from the stack (or the object it found by name). For each pointer to the object in the new closure, the reference count will be incremented, so that the original reference isn't used afterwards. There has to be at least on other efun or operator that leaks a reference count, because after I fixed this I still get object (but less than before) with more than one reference, so that they stay in the destructed object list. (I advised the driver to do a cleanup_all_objects every second.) It's hard to track down these, because CHECK_OBJECT_REF isn't complaining and the DEBUG-output from (de)ref_object is simply overwhelming for a normal object. But I have objects, that have four added references from closure_init_lambda (closure.c 1044), but only two substracted references from free_closure. Is this okay or should each added reference be accompanied by a substracted reference from free_closure? Greetings, Gnomi PS: These leaked references are the reason for the 95-99% CPU load we got... | ||||
Tags | No tags attached. | ||||
|
You are correct - it is now corrected. This also gave me an idea for where to look for the other missing reference - turns out that when freeing a bound unbound-lambda, the free_closure() did not remove the creator object reference of the unbound-lambda. |
|
There has to be at least one more leak somewhere near the closure handling. I got a door (loaded at preload) with several leaked references. Loading and destructing the same door later didn't leak this reference. Here's the part of the debug output, that's different. The two indented 'Sub' messages are missing in the output of the first door: Add ref to object obj/tuer#353: 35 (ass to var) interpret.c 1360 Add ref to object obj/tuer#353: 36 (lambda object) closure.c 1044 Sub ref from object obj/tuer#353: 35 (free_svalue) interpret.c 1111 Add ref to object obj/tuer#353: 36 (previous_object) interpret.c 19435 Add ref to object obj/tuer#353: 37 (ass to var) interpret.c 1360 Add ref to object obj/tuer#353: 38 (lambda object) closure.c 1044 Sub ref from object obj/tuer#353: 37 (free_svalue) interpret.c 1111 Add ref to object obj/tuer#353: 38 (this_object) interpret.c 16217 Add ref to object obj/tuer#353: 39 (assign_local_lvalue_no_free) interpret.c 1554 Add ref to object obj/tuer#353: 40 (assign_local_lvalue_no_free) interpret.c 1554 Sub ref from object obj/tuer#353: 39 (free_svalue) interpret.c 1111 Greetings, Gnomi |
|
See the added notes: replace_program_lambda_adjust() forgot to free the object references from the auxiliary lambda it created. |
|
Es geht nur um Clones. Die erste Tuer (/obj/tuer#13), wird von /room/church (die Kathedrale von Tadmor wir dim Preload geladen) geclont. Wenn ich danach /room/church zerstoere, wird auch diese Tuer zerstoert, hat aber 3 ueberfluessige Referenzen und bleibt daher ewig in der Liste der zerstoerten Objekte. Wenn ich dann wieder /room/church lade (und damit einen weiteren Clone - hier /obj/tuer#353 - erschaffe) und auch wieder zerstoere, werden die Referenzen ordentlich gezaehlt. Ich hab die Debugausgaben beider Objekte verglichen und der Unterschied lag eben in diesen fehlenden Sub-Meldungen. (Am Ende wird das Log etwas chaotischer, da kommen assign- und free_svalue-Meldungen in beliebiger Reihenfolge, aber der Anfang ist bis auf diese fehlenden Zeilen gleich und der Unterschied am Ende im Refcount entspricht genau der Anzahl dieser fehlenden Zeilen.) also ich kann es im HomeMUD rekonstruieren. Folgendes Programm bewirkt das auch: inherit "/i/tools/update_actions"; // Doesn't matter, something to inherit from. void create() { replace_program(); lambda(0,0); destruct(this_object()); } Beim replace_program wird fuer jede geschuetzte Lambda noch eine generiert. Diese erhaelt damit auch wieder eine Referenz auf das Objekt. Dann kopiert er die Daten von der neuen Lambda auf die alte Lambda und zerstoert anschliessend die neue Lambda mit einem xfree, also ohne die zugehoerige Referenz freizugeben. |
Date Modified | Username | Field | Change |
---|---|---|---|
2005-11-07 17:37 | Gnomi | New Issue | |
2005-11-08 01:08 |
|
Status | new => resolved |
2005-11-08 01:08 |
|
Fixed in Version | => 3.3 |
2005-11-08 01:09 |
|
Resolution | open => fixed |
2005-11-08 01:09 |
|
Assigned To | => lars |
2005-11-08 01:09 |
|
Note Added: 0000396 | |
2005-11-08 14:42 | Gnomi | Status | resolved => feedback |
2005-11-08 14:42 | Gnomi | Resolution | fixed => reopened |
2005-11-08 14:42 | Gnomi | Note Added: 0000397 | |
2005-11-09 09:41 |
|
Status | feedback => resolved |
2005-11-09 09:41 |
|
Resolution | reopened => fixed |
2005-11-09 09:41 |
|
Note Added: 0000398 | |
2005-11-09 09:43 |
|
Note Added: 0000399 | |
2006-02-28 20:05 |
|
Status | resolved => closed |
2010-11-16 09:42 |
|
Source_changeset_attached | => ldmud.git master 84b23cbb |
2010-11-16 09:42 |
|
Source_changeset_attached | => ldmud.git master 1a7da5b1 |
2018-01-29 18:59 |
|
Source_changeset_attached | => ldmud.git master 84b23cbb |
2018-01-29 18:59 |
|
Source_changeset_attached | => ldmud.git master 1a7da5b1 |
2018-01-29 21:57 |
|
Source_changeset_attached | => ldmud.git master 84b23cbb |
2018-01-29 21:57 |
|
Source_changeset_attached | => ldmud.git master 1a7da5b1 |