Matthew Gertner wrote:
> Hi,
> 
> We're using NSS inside a Windows app for encrypted communication.
> Everything works fine, but we're experiencing a large number of memory
> leaks. Tracking down the cause led me to the following stacktrace (among
> many others):
> 
> nspr4.dll!PR_Malloc(unsigned int size=2135)  Line 495 + 0xa    C
> plds4.dll!PL_ArenaAllocate(PLArenaPool * pool=0x03b4abc8, unsigned int
> nb=2112)  Line 214 + 0xa    C
> nss3.dll!PORT_ArenaAlloc(PLArenaPool * arena=0x03b4abc8, unsigned int
> size=2108)  Line 243 + 0x49    C

[snip]

> So basically we are creating a new SSL socket with
> [snip] memory allocated by the arena
> pool code. I can't see who is responsible for freeing this certificate
> (or rather the underlying memory block in the arena pool), but it does
> not appear to be freed ever.
> 
> Are we doing something obviously wrong? When and where are these
> certicates meant to be freed?

NSS makes extensive use of NSPR's PLArenaPools for memory allocation.

Each block of memory allocated in a PLArenaPool is called a PLArena.
When a PLArenaPool is freed, all the arenas in that pool are put on an
arena free list.  When NSS attempt to allocate more memory from an
arena pool, the PLArenaPool code attempts to use an arena from its
free list, and only gets a new arena from the heap if there are no
arenas in the free list that are large enough to satisfy the request.

There are two consequences of the use of PLArenaPools that affect
leak analysis.  They are:

1) At the end of execution of a program, all the arenas in the free
list will appear to have been leaked.  This makes it difficult to tell
arenas that are truly leaked from those that are merely in the free list.

There is a function named PL_ArenaFinish that really frees all the
arenas on the free list.  See the prototype at
http://lxr.mozilla.org/nspr/source/nsprpub/lib/ds/plarenas.h#79

Your program should call that function at the very end, after having
shutdown NSS and NSPR, to really free the contents of the free list.
After that function returns, any arenas that still appear to be leaked
have truly been leaked, and are not merely on the free list.

2) Leaked arenas that were most recently taken from the arena free list
will show the wrong stack trace for the place where they were allocated.
That is, a stack trace like the one you showed will typically NOT be
the true stack trace of the code that most recently allocated that arena,
but rather will be the stack of the code that FIRST allocated that
arena, and then placed it on the free list.  Of course, for leak analysis,
you really want to find the stack trace of the place that most recently
allocated that arena, not of some code that previously used it and then
freed it to the free list.

To solve that problem, it is generally necessary to disable the arena free
list, so that arenas are actually freed back to the heap each time they
are freed, and are allocated afresh from the heap each time they are
allocated.  This makes NSS slower, but produces accurate leak allocation
stacks.  To accomplish that, set an environment variable prior to the
initialization of NSS and NSPR.  This can be done outside the program
entirely, or can be done by the program itself, in the main() function.
Set the environment variable NSS_DISABLE_ARENA_FREE_LIST to have any
non-empty value, e.g. NSS_DISABLE_ARENA_FREE_LIST=1.

-- 
Nelson B
12345678901234567890123456789012345678901234567890123456789012345678901234567890
00000000011111111112222222222333333333344444444445555555555666666666677777777778
_______________________________________________
dev-tech-crypto mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-crypto

Reply via email to