looking for more info on EIO error returned by readdir_r () on Mac OS X - macos

On Mac OS X 10.6.8, some C code that calls readdir_r() sometimes gets an I/O error 5 (EIO) returned. I've seen this just a few times, always on external USB drives. Each time I've seen it, if I immediately cd to the parent direction and do an ls, I appear to see all the files. And, if I re-run the C program that saw the error, it will run fine.
On some platforms, when one gets an error like EIO, there's something else you can call that gives you much more detailed error information (e.g., hperrmsg on MPE/iX, which accesses the per-process error stack). Is there something similar on OS X?
I guess I'm assuming that the error is false
i = readdir_r (dirp, &dire, &dire_ptr);
save_errno = errno;
if (i)
{
if (i == EACCES)
...
else
{
my_perror (save_errno, "readdir_r failed: ");
espout4 ("readdir_r returned %s; errno = %s, dire_ptr = %s; parent = %s\n",
num64 (i), num64 (save_errno), fmt_p (dire_ptr), parent_dir);
espout1 (" (ERROR: readdir_r failed here, errno %s)\n", num64 (save_errno));
}
}

Update, a week later...
I've determined that the combo of the Macally case (model G-S350SU)
and the Western Digital drive was causing sporadic problems. I noticed that the WD SATA connector didn't mate tightly with the Macally socket. Using a Seagate drive with the case was fine, and using the WD drive in a different case was fine.
Of course, I'd still like to be able to get better / more detailed error information in my programs :)

Related

Rshell on windows freezes randomly while sending files to ESP32 running micropython via rsync or cp

I'm having trouble copying files to ESP32 device running micropython via rshell (remote micropython shell). The problem seems to occur randomly. Sometimes I manage to successfuly send all files (like 20 of them) with rsync and sometimes I cannot even copy one file with cp. There is no error message and script doesn't crash, it just stops working and freezes the console. I've tried with and without -a parameter (I'm sending only .py files). The last thing printed with debug is code to be run on microcontroller below and it just stops there. I didn't find any pattern. I've tried using some other esp32 device and other windows PC. Same results. I even tried lowering default 32 buffer to 16, no improvement. The worst thing is that is sometimes works fine and I cannot get constant results (even bad). It stops on random files, not always the same one.
Rsync command (with --mirror parameter) is very helpful and I could not just copy all files by hand.
EDIT: just tested on mac and it works fine. I guess it's just problem on windows...
Adding /pyboard/protocol/parser.py
----- About to send 2269 bytes of code to the pyboard -----
def recv_file_from_host(src_file, dst_filename, filesize, dst_mode='wb'):
"""Function which runs on the pyboard. Matches up with send_file_to_remote."""
import sys
import ubinascii
import os
if False:
try:
import pyb
usb = pyb.USB_VCP()
except:
try:
import machine
usb = machine.USB_VCP()
except:
usb = None
if usb and usb.isconnected():
# We don't want 0x03 bytes in the data to be interpreted as a Control-C
# This gets reset each time the REPL runs a line, so we don't need to
# worry about resetting it ourselves
usb.setinterrupt(-1)
try:
with open(dst_filename, dst_mode) as dst_file:
bytes_remaining = filesize
if not False:
bytes_remaining *= 2 # hexlify makes each byte into 2
buf_size = 32
write_buf = bytearray(buf_size)
read_buf = bytearray(buf_size)
while bytes_remaining > 0:
# Send back an ack as a form of flow control
sys.stdout.write('\x06')
read_size = min(bytes_remaining, buf_size)
buf_remaining = read_size
buf_index = 0
while buf_remaining > 0:
if False:
bytes_read = sys.stdin.buffer.readinto(read_buf, read_size)
else:
bytes_read = sys.stdin.readinto(read_buf, read_size)
if bytes_read > 0:
write_buf[buf_index:bytes_read] = read_buf[0:bytes_read]
buf_index += bytes_read
buf_remaining -= bytes_read
if False:
dst_file.write(write_buf[0:read_size])
else:
dst_file.write(ubinascii.unhexlify(write_buf[0:read_size]))
if hasattr(os, 'sync'):
os.sync()
bytes_remaining -= read_size
return True
except:
return False
output = recv_file_from_host(None, '/protocol/parser.py', 1467)
if output is None:
print("None")
else:
print(output)
-----
I had the same problem ,
when trying
C:\> cp src\main.py /pyboard/
the cmd freezes.
When I copied using the following
C:\> cp src/main.py /pyboard/
There where no issues, so maybe rshell has some problems when there are "\" in the path

How to open USB device in OSX

I'm finally able to get the device path ("/dev/rdisk1") - called devname here - after a search but POSIX open() fails with -1. Is this a permission issue? The camera is mounted and can be read normally via /Volumes but I need to access via /dev to control the camera via USB tether.
/* Found PENTAX DIGITAL_CAMERA */
snprintf(pslr.devname, sizeof(pslr.devname), "%s", devpath);
pslr.devname[sizeof(pslr.devname)-1] = '\0';
printf("pslr.devname %s\n", pslr.devname);
pslr.fd = open(pslr.devname, O_RDWR);
if (pslr.fd == -1) {
return NULL;
}
PS: after the discussion below I changed the permissions with sudo chmod command and then tried open but it still fails. I must be missing a step.
I checked with apple support and they say I cannot use posix functions to control a USB device in OS X.

Find process where a particular system call returns a particular error

On OS X El Capitan, my log file system.log feels with hundreds of the following lines at times
03/07/2016 11:52:17.000 kernel[0]: hfs_clonefile: cluster_read failed - 34
but there is no indication of the process where this happens. Apart from that, Disk Utility could not find any fault with the file system. But I would still like to know what is going on and it seems to me that dtrace should be perfectly suited to find out that faulty process but I am stuck. I know of the function return probe but it seems to require the PID, e.g.
dtrace -n 'pidXXXX::hfs_clonefile:return { printf("ret: %d", arg1); }'
Is there a way to tell dtrace to probe all processes? And then how would I print the process name?
You can try something like this (I don't have access to an OS X machine to test it)
#!/usr/sbin/dtrace -s
# pragma D option quiet
fbt::hfs_clonefile:return
/ args[ 1 ] != 0 /
{
printf( "\n========\nprocess: %s, pid: %d, ret value: %d\n", execname, pid, args[ 1 ] );
/* get kernel and user-space stacks */
stack( 20 );
ustack( 20 );
}
For the fbt probes, args[ 1 ] is the value returned by the function.
The dTrace script will print out the process name, pid, and return value from hfs_clonefile() whenever the return value is not zero. It also adds the kernel and user space stack traces. That should be more than enough data for you to find the source of the errors.
Assuming it works on OS X, anyway.
You can use the syscall provider rather than the pid provider to do this sort of thing. Something like:
sudo dtrace -n 'syscall::hfs_clonefile*:return /errno != 0/ { printf("ret: %d\n", errno); }'
The above command is a minor variant of what's used within the built-in DTrace-based errinfo utility. You can view /usr/bin/errinfo in any editor to see how it works.
However, there's no hfs_clonefile syscall, as least as far as DTrace is concerned, on my El Capitan (10.11.5) system:
$ sudo dtrace -l -n 'syscall::hfs*:'
ID PROVIDER MODULE FUNCTION NAME
dtrace: failed to match syscall::hfs*:: No probe matches description
Also, unfortunately the syscall provider is prevented from tracing system processes by the System Integrity Protection feature introduced with El Capitan (macOS 10.11). So, you will have to disable SIP which makes your system less secure.

Where does tmux keep logs on OS X

tmux has been crashing a lot lately, and I'm not sure why. I want to look into it further, but I don't know where I can find any kind of logs, or error messages. So far, my googling for "tmux log location" and the like has come up empty.
I'm running OS X, and installed tmux via Homebrew.
The manual page needs some work (you may not see the feature at first). But starting from the source code (referring to version 2.1 in tty.c) you may see
if (debug_level > 3) {
xsnprintf(out, sizeof out, "tmux-out-%ld.log", (long) getpid());
fd = open(out, O_WRONLY|O_CREAT|O_TRUNC, 0644);
if (fd != -1 && fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
fatal("fcntl failed");
tty->log_fd = fd;
}
The -v flag sets the debug_level value; repeating it increases the value. Back to the manual page:
-v
Request verbose logging. This option may be specified multiple times for increasing verbosity. Log messages will be saved into tmux-client-PID.log and tmux-server-PID.log files in the current directory, where PID is the PID of the server or client process.

Can I ask dtrace what probes are enabled?

If it matters, I am using Mac OS X, but I believe this would apply across OSs. If the answer is different per OS, I would be interested in learning about that as well.
Let's say that I open a terminal window, enable a few probes, and start collecting data with DTrace.
From a different terminal window, can I ask DTrace what probes have been enabled? If so, how?
I got the following information from Adam Leventhal on a DTrace mailing list. First, he provided this script, which works on Solaris
#!/usr/sbin/dtrace -s
#pragma D option quiet
int i;
tick-100
/i >= `dtrace_nprobes/
{
exit(0);
}
tick-100
{ printf("%4d %10s %20s %20s %10s %s\n", i,
stringof(`dtrace_probes[i]->dtpr_provider->dtpv_name),
stringof(`dtrace_probes[i]->dtpr_mod),
stringof(`dtrace_probes[i]->dtpr_func),
stringof(`dtrace_probes[i]->dtpr_name),
`dtrace_probes[i]->dtpr_ecb != NULL ? "enabled" : "disabled");
i++
}
Unfortunately, the same kernel variables are not available on Mac OS X due to a bug.

Resources