hi, I am trying to find out the amount of memory allocated by the user functions over time. The essential idea is pid$target:libc:malloc:entry { @mem[<here i need the user method that called malloc>] = sum(arg0); } or probably pid$target:libc:malloc:return /< predicate that would make sure that malloc succeeded: arg0 or arg1...not sure what>/ { @mem[<here i need the user method that called malloc>] = sum(<arg0 or arg1 here..not sure>); } further, i also want to update the @mem on free calls to correctly reflect if any method is responsible for any memory leaks. Problem: the parts in <> : not able to know in general the method which called a particular method. regards, pankaj
On Fri, Feb 17, 2006 at 04:56:47AM +0530, Pankaj Maurya wrote:> hi, > I am trying to find out the amount of memory allocated by the user > functions over time. The essential idea is > pid$target:libc:malloc:entry > { > @mem[<here i need the user method that called malloc>] = sum(arg0); > } > or probably > pid$target:libc:malloc:return > /< predicate that would make sure that malloc succeeded: arg0 or > arg1...not sure what>/ > { > @mem[<here i need the user method that called malloc>] = sum(<arg0 > or arg1 here..not sure>); > } >pid$target::malloc:entry { self->inmalloc = 1; self->size = arg0; } pid$target::malloc:return /self->inmalloc && arg1 != 0/ { @mem[ucaller()] = sum(self->size); } pid$target::malloc:return /self->inmalloc/ { self->inmalloc = 0; self->size = 0; }> further, i also want to update the @mem on free calls to correctly > reflect if any method is responsible for any memory leaks.That''s trickier; you''d have to keep track of all allocations in a big associative array. Have you considered using something like libumem(3lib)? Try doing: LD_PRELOAD=libumem.so UMEM_DEBUG=default ./program args (give it a bunch of load, then either SIGQUIT (C-\) or gcore(1) the process) echo "::findleaks -dv" | mdb corefile where corefile is the generated core file. That will give you stack traces of all of the leaks. Cheers, - jonathan> Problem: the parts in <> : not able to know in general the method which > called a particular method. > > regards, > pankaj > _______________________________________________ > dtrace-discuss mailing list > dtrace-discuss at opensolaris.org-- Jonathan Adams, Solaris Kernel Development
On Fri, Feb 17, 2006 at 05:42:23AM +0530, Pankaj Maurya wrote:> > >pid$target::malloc:return > >/self->inmalloc && arg1 != 0/ > >{ > > @mem[ucaller()] = sum(self->size); > >} > > > > > My solaris 10 installation did not recognize this method: ucaller(), > further I am refering to the Solaris Dynamic Tracing Guide, it also > didn''t provide me any information about this method. Kindly clarify how > I could use this method( any more libraries need to be installed or > something similar, also where I can get detailed information about such > extremely useful methods)I got the above wrong. It should be: pid$target::malloc:return /self->inmalloc && arg1 != 0/ { @mem[ufunc(ucaller)] = sum(self->size); } In any case, this will only work in Nevada/OpenSolaris. I''m not sure when it will appear in Solaris 10; it is not in Update 1. In Solaris 10, you could do: pid$target::malloc:return /self->inmalloc && arg1 != 0/ { @mem[ustack(1)] = sum(self->size); }> >>further, i also want to update the @mem on free calls to correctly > >>reflect if any method is responsible for any memory leaks. > >> > >> > > > >That''s trickier; you''d have to keep track of all allocations in a big > >associative array. Have you considered using something like libumem(3lib)? > >Try doing: > > > > LD_PRELOAD=libumem.so UMEM_DEBUG=default ./program args > > > >(give it a bunch of load, then either SIGQUIT (C-\) or gcore(1) the > >process) > > > > echo "::findleaks -dv" | mdb corefile > > > >where corefile is the generated core file. That will give you stack traces > >of all of the leaks. > > > > > > > I couldn''t follow this. I am a solaris newbie just picking up the basics > of dtrace. Please show me how to do the equivalent in dtrace.In dtrace, you''d have to do something like: pid$target::malloc:return { mallocsize[arg1] = self->size; } pid$target::free:entry /(this->size = mallocsize[arg0]) != 0/ { mallocsize[arg0] = 0; /* somehow undo the allocation */ } But what I''m suggesting is that you do this another way; set two environment variables before running your program: LD_PRELOAD=libumem.so UMEM_DEBUG=default,audit=40 Then run your program, induce load, and get a core file from it; to do so, you can use the gcore(1) command line: gcore pid which will stop the process, generate a core file named "core.pid", and start it running again. Then, do: echo "::findleaks -dv" | mdb core.pid | less which will look for memory leaks in the core file, and print out a full report of all of them. This is a much better tool to use for this kind of thing than dtrace. Cheers, - jonathan -- Jonathan Adams, Solaris Kernel Development
Pankaj, I have a script which does this for you. Refer to : http://blogs.sun.com/roller/page/sanjeevb?anchor=dtrace_to_identify_memory_leaks However, as Jonathan said, the best way to do it will be to use libumem as it has many more features which are useful. Hope that helps. Regards, Sanjeev. Jonathan Adams wrote:>On Fri, Feb 17, 2006 at 05:42:23AM +0530, Pankaj Maurya wrote: > > >>>pid$target::malloc:return >>>/self->inmalloc && arg1 != 0/ >>>{ >>> @mem[ucaller()] = sum(self->size); >>>} >>> >>> >>> >>> >>My solaris 10 installation did not recognize this method: ucaller(), >>further I am refering to the Solaris Dynamic Tracing Guide, it also >>didn''t provide me any information about this method. Kindly clarify how >>I could use this method( any more libraries need to be installed or >>something similar, also where I can get detailed information about such >>extremely useful methods) >> >> > >I got the above wrong. It should be: > >pid$target::malloc:return >/self->inmalloc && arg1 != 0/ >{ > @mem[ufunc(ucaller)] = sum(self->size); >} > >In any case, this will only work in Nevada/OpenSolaris. I''m not sure when >it will appear in Solaris 10; it is not in Update 1. In Solaris 10, you >could do: > >pid$target::malloc:return >/self->inmalloc && arg1 != 0/ >{ > @mem[ustack(1)] = sum(self->size); >} > > > > >>>>further, i also want to update the @mem on free calls to correctly >>>>reflect if any method is responsible for any memory leaks. >>>> >>>> >>>> >>>> >>>That''s trickier; you''d have to keep track of all allocations in a big >>>associative array. Have you considered using something like libumem(3lib)? >>>Try doing: >>> >>> LD_PRELOAD=libumem.so UMEM_DEBUG=default ./program args >>> >>>(give it a bunch of load, then either SIGQUIT (C-\) or gcore(1) the >>>process) >>> >>> echo "::findleaks -dv" | mdb corefile >>> >>>where corefile is the generated core file. That will give you stack traces >>>of all of the leaks. >>> >>> >>> >>> >>> >>I couldn''t follow this. I am a solaris newbie just picking up the basics >>of dtrace. Please show me how to do the equivalent in dtrace. >> >> > >In dtrace, you''d have to do something like: > >pid$target::malloc:return >{ > mallocsize[arg1] = self->size; >} > >pid$target::free:entry >/(this->size = mallocsize[arg0]) != 0/ >{ > mallocsize[arg0] = 0; > /* somehow undo the allocation */ >} > >But what I''m suggesting is that you do this another way; set two environment >variables before running your program: > > LD_PRELOAD=libumem.so > UMEM_DEBUG=default,audit=40 > >Then run your program, induce load, and get a core file from it; to do so, >you can use the gcore(1) command line: > > gcore pid > >which will stop the process, generate a core file named "core.pid", and start >it running again. Then, do: > > echo "::findleaks -dv" | mdb core.pid | less > >which will look for memory leaks in the core file, and print out a full >report of all of them. > >This is a much better tool to use for this kind of thing than dtrace. > >Cheers, >- jonathan > > > >