talloc_tos in shadow_copy2_insert_string

Andrew Klaassen clawsoon at yahoo.com
Tue Mar 27 11:03:17 MDT 2012


--- On Tue, 3/27/12, Volker Lendecke <Volker.Lendecke at SerNet.DE> wrote:

> From talloc_stackframe.h:
> 
> /*               
>  * Implement a stack of talloc frames.     
>  *               
>  * When a new talloc stackframe is allocated with
>  * talloc_stackframe(), then     
>  * the TALLOC_CTX returned with talloc_tos() is reset to
>  * that new           
>  * frame. Whenever that stack frame is TALLOC_FREE()'ed,
>  * then the reverse       
>  * happens: The previous talloc_tos() is restored. 
>  *               
>  * This API is designed to be robust in the sense that if
>  * someone forgets to    
>  * TALLOC_FREE() a stackframe, then the next outer one
>  * correctly cleans up and  
>  * resets the talloc_tos().       
>  *               
>  */
> 
> The intended use is that talloc_tos() is used for anything
> within a function. Returning something on talloc_tos() is
> not the best style, because it means that this object will
> go away once the surrounding talloc_stackframe() goes. It
> will work okay if used in a controlled manner, but
> depending on local circumstances alternatives might be more
> understandable.

I read that code comment a few times but didn't fully understand it; thanks for the further explanation.

I've noticed this in my testing:

static void bar_alloc_string(char *barstring)
{
        barstring = talloc_asprintf(talloc_tos(), "%s/%s", "foo", "bar");
}

static char *baz_alloc_string(void)
{
        char *bazstring;
        bazstring = talloc_asprintf(talloc_tos(), "%s/%s", "foo", "bar");
        return bazstring;
}

static int vfs_tallocfoobar_stat(vfs_handle_struct *handle,
                           struct smb_filename *smb_fname)
{
        char *barstring = NULL;
        bar_alloc_string(barstring);

        DEBUG(0, ("bar string -> '%s'\n", barstring));
        /* outputs "bar string -> '(null)'" */
        /* Freed. */

        DEBUG(0, ("baz string -> '%s'\n", baz_alloc_string()));
        /* outputs "baz string -> 'foo/baz'" */
        /* Not freed. */
}

I am right to guess based on this (before finding some proper documentation to read) that memory on a function's stack which is returned with "return" (rather than attached to a passed-in pointer) gets attached to the caller's stack, and that's why talloc isn't automatically freeing the baz result?

Thanks again for your help.

Andrew




More information about the samba-technical mailing list