[Asterisk-Dev] potentially nasty bugs in string pools usage
Kevin P. Fleming
kpfleming at digium.com
Fri Jan 6 12:40:17 MST 2006
Luigi Rizzo wrote:
> ok. but please also write down some commments on who is allowed to work
> on the allocator and when. With malloc, you rely on malloc's implementation;
> with a different allocator, the allocator needs to rely on some other lock,
> but this cannot be the structure's lock because not all structs have one,
> and even for those who do, it is not clear (and not documented) which
> strings are protected by the lock and which are not.
I will think about this some more over the next few days; given the
application, it may make some sense to just document that string fields
are not something that you can preserve pointers to while you manipulate
the structure, and that you have to make copies of the fields in extreme
cases. I'm not sure that's the best option, but it's one way to solve it.
> For performance, you could just vsnprintf() into a reasonably large
> local buffer (say 1k instead of 1 byte as you do now), and then
> copy the result. The copy is a lot cheaper than re-parsing the
> format string and running expensive conversions e.g. from numbers
> to digits (anyways, rerunning the snprintf involves copying as
> well). Probably a size of 1024 will cover 99% of the cases.
That is very true, and even 512 bytes would be enough, since the fields
that we are replacing were never that large to begin with.
> BTW i don't understad why you want to use a macro for
> ast_string_field_index_build() when you can just make it a var-adic
> function which then calls vsnprintf as many times as needed.
> You have to go through the var-adic function anyways.
If it was a direct function call, the caller would have to provide the
address of the hidden 'implementation' bits that are inside the
structure. The macro provides a way to pass only a pointer to the
structure instance, but still learn where those implementation bits are
located, thus hiding the implementation.
> i don't buy how it individually malloc'ed strings could use more
> memory than a single pool. unless the malloc in your system has an
> unreasonably large minimum chunk size. Can you explain that ?
Some of the string beings stored in my tests were quite short, and
malloc() on my system seems to consume 16 bytes plus the allocation
request. That may be due to the fact that I'm running on a 64-bit box,
though.
> I was just commenting that since some of the bugs introduced by this
> change could be rather obscure (see the realloc one and the locking
> issues), personally i would first try to push the new interface in
> as many places as possible, and at a later time (or in parallel,
> if you like) address the performance issues underneath.
> I'd be happy with a 'safe_stringfield' mode where strings are
> malloced individually, and a default mode where you use your
> allocator. So when a bug comes out you try to see if it is also
> present in the safe mode and this can help a lot in debugging.
That's certainly a good idea as well. We could even do that when
MALLOC_DEBUG is defined... Mark suggested adding some performance
metrics (viewable via a CLI command) to the string field manager when
MALLOC_DEBUG is on, so we can see how it is being used as well.
More information about the asterisk-dev
mailing list