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
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.
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
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.