[Mono-list] Mono.Unix.Native.Syscall.readlink memory corruption
Jonathan Pryor
jonpryor at vt.edu
Tue Mar 14 13:43:49 EST 2006
On Tue, 2006-03-14 at 11:33 +0000, Colin JN Breame wrote:
> On Tuesday 14 March 2006 00:16, Jonathan Gilbert wrote:
> > At 04:12 PM 13/03/2006 -0500, Gonzalo Paniagua Javier wrote:
> > >On Mon, 2006-03-13 at 17:32 +0000, Colin JN Breame wrote:
> > >> using System.Text;
> > >> public class main_t {
> > >> public static void Main() {
> > >> for (int i=0; i<10000; i++) {
> > >> StringBuilder buf = new StringBuilder();
> > >> Mono.Unix.Native.Syscall.readlink("path/to/link/file", buf);
> > >> }
> > >> }
> > >> }
> > >
> > >Confirmed. I get the same error.
> >
> > Don't you need to give the StringBuilder a capacity first? Is the default
> > capacity documented, and documented to be large enough for the return value
> > of readlink()?
> >
>
> Look like the default capacity is the capacity of the StringBuilder passed, so
> setting the Length of the buffer seems to solve the problem. A test for zero
> length would probably be useful:
The test isn't useful, as readlink(2) _already_ does this check (and is
documented as returning -1 with errno = EINVAL if the buffer size is
incorrect). Furthermore, the default StringBuilder capacity is 16, not
0, so 0 really shouldn't ever be passed.
What's more confusing is this: if I run your program inside gdb, set a
breakpoint inside Mono_Posix_Syscall_readlink, and print out `len' (the
buffer length argument), I get bizarre random values (e.g. 290704).
*That* is the fundamental problem: the buffer length argument doesn't
match the StringBuilder capacity.
Oddly, if I use the Syscall.readlink(string,StringBuilder,ulong)
overload, I don't see any problems at all.
Odder, all Syscall.readlink(string,StringBuilder) does is invoke
Syscall.readlink(string,StringBuilder,ulong) with the final argument set
to (ulong)StringBuilder.Capacity.
I have no idea why this is happening (a botched svn build?).
> As in the C world we known MAX_PATH, might it not be better to change the
> semantics of the call so that it returns the path?
MAX_PATH is always a bad idea, as it changes from filesystem to
filesystem. Also, some systems don't have a MAX_PATH, such as GNU HURD.
> On a related note: if a C function mallocs some memory and returns a pointer
> to that memory, does p/invoke free the memory once marshalling is complete?
It depends on the return type of the managed function. Class types will
have the pointer freed through g_free (Mono) or CoTaskMemFree (.NET).
Struct types won't have the type automatically freed, so using IntPtr
won't let the runtime free your pointer.
- Jon
More information about the Mono-list
mailing list