site_archiver@lists.apple.com Delivered-To: darwin-dev@lists.apple.com * Returns: 0 Success * EBADF * EFAULT * fp_lookup:EBADF Bad file descriptor * vnode_getwithref:??? * copyout:EFAULT * vnode_getwithref:??? * vn_stat:??? * soo_stat:??? * pipe_stat:??? * pshm_stat:??? * kqueue_stat:??? - In general, though, its: Also, on the detrace question: -- Terry _______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-dev mailing list (Darwin-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-dev/site_archiver%40lists.appl... On Jan 16, 2009, at 12:37 PM, Joel Reymont wrote: On Jan 16, 2009, at 8:25 PM, Jason Coco wrote: It's a syscall, so it's only a stub in libc. It's actually defined in the kernel (the xnu module). A follow-up question then... under what conditions can fstat return EINVAL (invalid argument)? I can call fstat for stdin, stdout and stderr just fine but as soon as I give it my fd (opened read-only), it gives me an error. I'll go dig through the kernel sources in the meantime. There is a lot of block comment documentation in xnu in bsd/kern/ kern_descrip.c on fstat which tells what error codes can come from where. Unless you are calling this on a weird descriptor, here are the documented returns: The ??? means you're calling it on a weird descriptor, and the code will return whatever it returns as an implementation detail of the descriptor. In general, it means code hat a user might supply or an NKE a user might supply could return a value other than one of the documented error codes here. Typically, this will only happen if someone has written a bogus kernel extention, but, hey, we don't know what code you have loaded into your kernel. Since you came back later and said that the actual call was ftruncate, not fstat, the function you want to look at is actually implemented in xnu in bsd/vfs/vfs_syscalls.c. As I did not need the error codes to change to pass UNIX conformance testing, I didn't not check the origin of the error code and trace them back to their distal causes in the functions called from that function. EINVAL (you told it to truncate to a negative length) fp_lookup:EBADF pshm_truncate:EINVAL (the shared memory segment was already deleted; release your reference, already!) pshm_truncate:EINVAL (the shared memory segment was allocated, but you're failed to initialize it yet) pshm_truncate:EINVAL (mach_make_memory_entry_64 failed, probably because you initialized things wrong) pshm_truncate:ENOMEM (there isn't enough memory; maybe you need to buy more RAM or compile 64 bit?) pshm_truncate:EACCES (it's not mapped for that) EINVAL (you told it to truncate a file type that wasn't a vnode or POSIX shared memory segment) EINVAL (you told it to truncate a vnode, but you didn't open the file for write) vnode_getwithref:EINVAL (the file is not open for write) vnode_getwithref:ENOENT (your node is dead, probably because your FS is corrupted) vnode_setattr:EROFS (you told it to truncate a read-only file; you can't expect to write ROMs) vnode_setattr:??? (whatever the filesystem implementation can return for VNOP_SETATTR; if iit's one of ours, this won't happen) You want to do what's called a speculative function boundary trace, and check the error return on the function you are tracing for EINVAL; if you get an EINVAL, then commit the speculative trace, otherwise, discard it. When you get output for the speculative trace, then it will be the call stack that resulted in the EINVAL being returned. In general, since the error code being returned is not examined/set with an accessor/mutator function, and if it were, the function would most likely be inlined, there's not really a tracepoint for you to trap on in order to trace such things (one of the many reasons programmers should not use data interfaces for important things, and one of the many performance reasons that they do anyway). However, even if you got a trace on the EINVAL set point, that would only give you a proximal cause ("something failed somewhere down the call stack, and that error eventuall bubbled up to here, so I set the BSD error code EINVAL"), so a speculative trace would really be the best way to go in any case. There are a lot of really good examples of how to use this in the Sun DTrace guide. PS: My wild educated guess is you are passing a negative number to the truncate; this will typically happen if you attempt to use something other than an off_t (signed 64 bit) parameter to ftruncate(), and failed to have a prototype in scope at the time you made the call, and then half your 32 bit value happens to be whatever 32 bits of garbage were already in the other register -- you can compile with -Wall - Werror compiler options to catch things like this at compile time. This email sent to site_archiver@lists.apple.com
participants (1)
-
Terry Lambert