talloc_tos in shadow_copy2_insert_string

Jeremy Allison jra at samba.org
Tue Mar 27 14:58:33 MDT 2012


On Tue, Mar 27, 2012 at 12:33:52PM -0700, Andrew Klaassen wrote:
> --- On Tue, 3/27/12, Jeremy Allison <jra at samba.org> wrote:
> 
> > This is just straight C programming.
> > 
> > static void bar_alloc_string(char *barstring)
> > {
> >     barstring = talloc_asprintf(talloc_tos(),
> > "%s/%s", "foo", "bar");
> > }
> > 
> > Overwrites the passed in barstring (which was NULL) with
> > the talloc'd value. This is then not returned (although
> > kept on the talloc_tos() pointer). It will be kept around
> > and only freed when the current talloc_tos() pointer
> > frame is freed.
> 
> Apologies for beating this horse some more, but it looks like I'm still not understanding parts of talloc's behaviour.  If you can spare a few more cycles I'd very much appreciate it.
> 
> In this pair of functions, I'd expect clientFname to stick around until the second function returns, since all talloc operations on it use the talloc_tos() from the second function for context.  But, instead, it gets freed as soon as the first function returns:
> 
> static int do_the_clone_of_smb_fname(struct vfs_handle_struct *handle,
>                 TALLOC_CTX *mem_ctx,
>                 struct smb_filename *smb_fname,
>                 struct smb_filename *clientFname)
> {
>         /* Use mem_ctx from caller. */
>         copy_smb_filename(mem_ctx, smb_fname,
>                         &clientFname);
> 
>         DEBUG(0, ("1 clientFname->base_name '%s'\n",
>                  clientFname->base_name));
>         /* prints expected basename. */
> 
> }
> 
> static int clone_smb_fname_stat(vfs_handle_struct *handle,
>                 struct smb_filename *smb_fname)
> {
>         struct smb_filename *clientFname = NULL;
> 
>         TALLOC_CTX *mem_ctx = talloc_tos();
> 
>         do_the_clone_of_smb_fname(handle, mem_ctx,
>                         smb_fname, clientFname);
> 
>         DEBUG(0, ("2 clientFname '%s'\n", clientFname));
>         /* prints (null)
>          * Shouldn't clientFname still be allocated and accessible,
>          * since all talloc operations on it use the talloc_tos()
>          * from this function as the context?  But, instead, we
>          * get null...
>          */        
> }

Again, this is simple C semantics, nothing talloc related.

Your function:

static int do_the_clone_of_smb_fname(struct vfs_handle_struct *handle,
                TALLOC_CTX *mem_ctx,
                struct smb_filename *smb_fname,
                struct smb_filename *clientFname)

is passed a *COPY* of the clientFname pointer (which
is NULL), and then you talloc something and assign
it into that copy of the pointer on the stack, which
is discarded (although not freed) when the function
returns. I suggest you look up the details of pointer
semantics in C.

What you're trying to do is :

static int do_the_clone_of_smb_fname(struct vfs_handle_struct *handle,
                TALLOC_CTX *mem_ctx,
                struct smb_filename *smb_fname,
                struct smb_filename **pp_clientFname)

Note the double ** denoting a double indirected pointer.
Assign to *pp_clientFname inside the function and you'll
get the talloc'ed value back.

Also note that a talloc_free'd pointer is not automatically
nulled.

Jeremy.


More information about the samba-technical mailing list