Is double close in strace necessarily bad?

Question:

I am training a neural network. Somewhere in my code base, I have a code snippet like the following:

def foo():
    d = {}
    with PIL.Image.open(img_path) as img:
        d["img"] = torchvision.transforms.functional.to_tensor(img)
    return d

This code doesn’t cause any problems. However, when I run my program under strace, I see that there is a double call of the close syscall (below, I omit everything except relevant strace lines):

openat(AT_FDCWD, "example.tif", O_RDONLY|O_CLOEXEC) = 3</tmp/example.tif>
fstat(3</tmp/example.tif>, {st_mode=S_IFREG|0644, st_size=9274, ...}) = 0
lseek(3</tmp/example.tif>, 0, SEEK_CUR) = 0
lseek(3</tmp/example.tif>, 0, SEEK_SET) = 0
read(3</tmp/example.tif>, "II*250#200 P8$26r7204BaP270d63517210DbQ8244"..., 4096) = 4096

# here some more lseeks and reads are omitted

mmap(NULL, 1765376, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7feb10bbd000
fcntl(3</tmp/example.tif>, F_DUPFD_CLOEXEC, 0) = 4</tmp/example.tif>
lseek(4</tmp/example.tif>, 0, SEEK_SET) = 0
read(4</tmp/example.tif>, "II*250#", 8) = 8
fstat(4</tmp/example.tif>, {st_mode=S_IFREG|0644, st_size=9274, ...}) = 0
mmap(NULL, 9274, PROT_READ, MAP_SHARED, 4</tmp/example.tif>, 0) = 0x7feb9e7a4000
munmap(0x7feb9e7a4000, 9274)            = 0
close(4</tmp/example.tif>) = 0
close(4)                                = -1 EBADF (Bad file descriptor)
close(3</tmp/example.tif>) = 0

I am worried about close(4) = -1 EBADF (Bad file descriptor). We can see that there is a duplicate call to the close syscall for some reason. The code works fine though. But still, does this necessarily mean that I have a bug in my code?


Upd: if anyone is interested, I have compiled a minimal self-contained example and reported the bug at https://github.com/python-pillow/Pillow/issues/7042

Asked By: CrabMan

||

Answers:

I would try to find out what causes this. In this particular example it seems OK, but there is room for very subtle errors. Imagine that you have a second thread, which open()s a file between the first and second close(4). It is likely, that this file descriptor get fd 4 assigned, and therefore will be closed immediately. This kind of error is a nightmare to debug.

Answered By: Rudi