Excellent work.  I haven't had time to track this down but I suspected that
nv_delete() had missing free() calls.

I verified that the leak is gone with this change.


On Tue, Feb 10, 2015 at 3:42 PM, Paulo César Pereira de Andrade <
paulo.cesar.pereira.de.andr...@gmail.com> wrote:

> Starting over as now I have a working patch that does not show
> any regressions in the ksh test cases, as it just release memory
> just before it would become unreachable.
>
> Simplified test case:
> ---8<---
> typeset -A stuff
> typeset -lui i=0
> for (( i=0; i<1000; i++ ))
> do
>     unset stuff[xyz]
>     typeset -A stuff[xyz]
>     stuff[xyz][elem0]="data0"
>     stuff[xyz][elem1]="data1"
>     stuff[xyz][elem2]="data2"
>     stuff[xyz][elem3]="data3"
>     stuff[xyz][elem4]="data4"
> done
> ---8<---
>
> Patch:
> ---8<---
> diff -up ksh-20120801/src/cmd/ksh93/sh/name.c.orig
> ksh-20120801/src/cmd/ksh93/sh/name.c
> --- ksh-20120801/src/cmd/ksh93/sh/name.c.orig    2015-02-10
> 17:15:37.180783550 -0200
> +++ ksh-20120801/src/cmd/ksh93/sh/name.c    2015-02-10 18:25:51.726228437
> -0200
> @@ -1298,7 +1298,16 @@ void nv_delete(Namval_t* np, Dt_t *root,
>          if(dtdelete(root,np))
>          {
>              if(!(flags&NV_NOFREE) && ((flags&NV_FUNCTION) ||
> !nv_subsaved(np,flags&NV_TABLE)))
> +            {
> +                Namarr_t    *ap;
> +                if(nv_isarray(np) && np->nvfun &&
> (ap=nv_arrayptr(np)) && array_assoc(ap)) {
> +                    while(nv_associative(np,0,NV_ANEXT))
> +                        nv_associative(np, 0, NV_ADELETE);
> +                    nv_associative(np, 0, NV_AFREE);
> +                    free((void*)np->nvfun);
> +                }
>                  free((void*)np);
> +            }
>          }
>  #if 0
>          else
> ---8<---
>
> I believe the patch checks all it should, but I just learned by reading
> code,
> enough of the logic to come up with the patch. It may be required for
> non associative arrays as well.
>
> np->nvfun is aka the "ap" in
> nv_associative(...) {
> ...
>         case NV_AINIT:
>         if(ap = (struct assoc_array*)calloc(1,sizeof(struct assoc_array)))
> ...
>
> The loop calling nv_associative with NV_ANEXT, NV_ADELETE, and
> NV_AFREE is to release all "foo[xyz]" in the test case, before it
> is overwritten, and the previous memory becomes unreachable.
>
> Thanks,
> Paulo
> _______________________________________________
> ast-users mailing list
> ast-users@lists.research.att.com
> http://lists.research.att.com/mailman/listinfo/ast-users
>
_______________________________________________
ast-users mailing list
ast-users@lists.research.att.com
http://lists.research.att.com/mailman/listinfo/ast-users

Reply via email to