Crash After Write in Linux

commenting out a printk statement causes crash in a linux device driver test

Accessing memory-mapped registers by simple C constructs such as *(vaddr + REG_IOCTL_ARG/4) is a bad idea. You might get away with it on some platforms if the access is volatile-qualified, but it won't work reliably or at all on some platforms. The proper way to access memory-mapped registers is via the functions declared by #include <asm/io.h> or #include <linux/io.h>. These will take care of any arch-specific requirements to ensure that writes are properly ordered as far as the CPU is concerned1.

The functions for memory-mapped register access are described in the Linux kernel documentation under Bus-Independent Device Accesses.

This code:

        *(vaddr + REG_IOCTL_ARG/4) = virt_to_phys(args);
*(vaddr + REG_IOCTL_CMD/4) = cmdx;

can be rewritten as:

        writel(virt_to_phys(args), vaddr + REG_IOCTL_ARG/4);
writel(cmdx, vaddr + REG_IOCTL_CMD/4);

1 Write-ordering for specific bus types such as PCI may need extra code to read a register inbetween writes to different registers if the ordering of the register writes is important. That is because writes are "posted" asynchronously to the PCI bus, and the PCI device may process writes to different registers out of order. An intermediate register read will not be handled by the device until all preceding writes have been handled, so it can be used to enforce ordering of posted writes.

C++: Linux: TCP/IP program crashes when calling write()

Assuming Linux >= 2.2, replace this:

n = write(newsockfd,data.c_str(),data.length()+1);

with this:

n = send(newsockfd, data.c_str(), data.length()+1, MSG_NOSIGNAL);

send(2) will then return -1 with errno set to EPIPE, rather than generating a fatal SIGPIPE. Alternatively, ignore SIGPIPE.

When you receive the SIGPIPE, the connection behind newsockfd has been broken. We don't have enough code to reproduce the problem, client and server, so it's rather moot to say what might actually be wrong. However, converting SIGPIPEs to EPIPEs will at least give your server a chance to handle the broken connection.

write(socket, buff, length) makes crash

You are writing to a closed socket, which by default generates a "broken pipe" signal (SIGPIPE). To be able to reliably recover from write(), you need to ignore EPIPE by calling:

signal (SIGPIPE, SIG_IGN);

somewhere in your program, for example in main().



Related Topics



Leave a reply



Submit