On Jan 18, 2007, at 4:45 PM, David Gatwood wrote:
On Jan 18, 2007, at 12:28 PM, Greg <email@hidden> wrote:
I'm not very familiar with kernel controls but I have a feeling that
the kernel panics are coming from how I'm using them, mainly because
I simply do not know very much about how they work (there's not much
documentation on them). The panic itself seems to occur when
data is
sent out (ctl_enqueue'd), although I have no way of being certain.
It seems to have something to do with memory allocation. One other
thing is that at the end of my ctl_sendfunc (called when the client
sends data to the kext), I always call mbuf_freem() on the mbut_t
structure passed in, I saw this done in some Brian's Peer-Guardian
source, however I don't know anything about its proper usage.
Short answer: don't free the buffer.
Long answer: If you really need to free mbufs, you probably should be
using freem_list so that it will clean up an mbuf chain, but
failing to
do so would just cause a slight leak, not a panic. However, in
this case,
you are actually causing a double free.
The calling code does appear to release the mbuf, though I had to
trace my
way back a half dozen functions to find where it does. If you look
at the
file "kern/uipc_socket.c" in the xnu sources, you'll see what's
going on.
At about line 1401 (depending on what version you're looking at),
when it
dereferences the function pointer:
*so->so_proto->pr_usrreqs->pru_send
it is (through an intermediary function) calling your ctl_send_func
callback.
Then, it releases the entire mbuf chain. Since your send function
essentially
turned one node somewhere in that chain into a dangling reference
to an
already-freed object, the behavior of the second free will behave
somewhat
nondeterministically, depending on what else is allocating or
releasing
memory at the time.
I'll add something to the docs the next time it gets updated.
I just wanted to chime in here, since my code was referenced. When I
started my project, it was on 10.4.2 and I originally did not free
the incoming mbuf. However, I then noticed an immediate mbuf leak
using netstat -m and fairly quickly, all mbufs were exhausted on the
machine. Adding in the free solved the problem. Also, this code has
been running on all versions of 10.4.2+ since Fall 2005 without issue.
Finally, looking at the code you referenced Dave (using
xnu-792.6.61), the mbuf is not freed as pru_send is called in the
while(resid) loop and top/control are zero'd at the end of every
iteration of that loop.
error = (*so->so_proto->pr_usrreqs->pru_send)(so,
sendflags, top, addr, control, p);
So which is it for ctl_send: free or don't?
Brian Bergstrand
<http://www.bergstrand.org/brian/> PGP Key ID: 0xB6C7B6A2
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (Darwin)
iD8DBQFFr//VedHYW7bHtqIRAtBWAKDO5nafLyU0lZfpHgLPEiR9MD4jVQCg2pLQ
Vg/mR3ETLZkxhPPXiHlAHdM=
=AhVJ
-----END PGP SIGNATURE-----
------------------------------