summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2012-07-18 04:57:31 +0930
committerRusty Russell <rusty@rustcorp.com.au>2012-07-18 04:57:31 +0930
commit84fb37fe372bc22e0a3ceca8030bff459225044a (patch)
tree6441b5162da2cedfc39d4b954366f3d4a05df5aa
parentf9b51ff33e10aa126de848072e98b0bf36a7dbc7 (diff)
downloadsamba-84fb37fe372bc22e0a3ceca8030bff459225044a.tar.gz
samba-84fb37fe372bc22e0a3ceca8030bff459225044a.tar.bz2
samba-84fb37fe372bc22e0a3ceca8030bff459225044a.zip
talloc_stack: report lazy freeing (panic if DEVELOPER).
talloc_stackframe() stacks, so if you forget to free one, the outer one will free it. However, it's not a good idea to rely too heavily on this behaviour: it can lead to delays in the release of memory or destructors. I had an elaborate hack to make sure every talloc_stackframe() was freed in the exact same function it was allocated, however all bugs it caught were simply lazy freeing, so this patch just checks for that. This doesn't check for stackframes we don't free up on exit: that would be nice, but uncovers some uncomfortable (but probably harmless) cases. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
-rw-r--r--lib/util/talloc_stack.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/lib/util/talloc_stack.c b/lib/util/talloc_stack.c
index 304ea17d8c..be332af571 100644
--- a/lib/util/talloc_stack.c
+++ b/lib/util/talloc_stack.c
@@ -96,6 +96,17 @@ static int talloc_pop(TALLOC_CTX *frame)
(struct talloc_stackframe *)SMB_THREAD_GET_TLS(global_ts);
int i;
+ /* Catch lazy frame-freeing. */
+ if (ts->talloc_stack[ts->talloc_stacksize-1] != frame) {
+ DEBUG(0, ("Freed frame %s, expected %s.\n",
+ talloc_get_name(frame),
+ talloc_get_name(ts->talloc_stack
+ [ts->talloc_stacksize-1])));
+#ifdef DEVELOPER
+ smb_panic("Frame not freed in order.");
+#endif
+ }
+
for (i=ts->talloc_stacksize-1; i>0; i--) {
if (frame == ts->talloc_stack[i]) {
break;