Recently, a bug is really maddening. It is only caused by a simple type conversion. Let's talk about it here. This is the description of the interface called by the pwrite system. We pay attention to the last parameter:
Ssize_t pwrite (int fd, const void * Buf, size_t count, off_t offset );
We have an interface implementation:
Int storage_write_meta_info (int fd, void * data, int unit ){... off_t offset; int length; ssize_t N; lenght = sizeof (struct XXX); offset = unit * length; n = pwrite (FD, Data, length, offset );...}
The running environment is centos x86_64, and the actual off_t type is long, 8 bytes. Program After running for a long time, pwrite returns-1, and errno is (22: invalid argument ). Experienced users may already see the problem: when two int types are multiplied (that is Code The final result is generated when the unit * length is exceeded, and is truncated to the int type and saved somewhere. In this way, the truncated error value is assigned to offset, and the multiplication of the two completely ignores the type of the left offset. How can this problem be solved? You only need to perform a forced conversion for any of the variables multiplied by the offset = (Off_t) Unit * length or offset = unit * (Off_t) Length or offset = (Off_t) Unit * (Off_t) Length, but the previous Code pwrite does not report an error (but not necessarily true): offset = uint * sizeof (struct XXX); because the return value of sizeof is size_t, it is really an unsigned int, which is equivalent to an int * unsigned Int. The result of the operation is regarded as an unsigned int type, which happens to be out of bounds. So I would like to warn you to be cautious and careful when there are many conversions between different types of parameters in the program. The best advice is not to consolidate so many types!