Description
Summary
- OS: FreeBSD 13.1-STABLE
- Architecture: 64bit (amd64)
- Psutil version: psutil-5.9.1
- Python version: Python 3.8.13
- Type: core
Description
I have a FreeBSD 13.1-STABLE system using a custom kernel without COMPAT_FREEBSD7
and psutil.virtual_memory()
fails as follows:
aspire5$ python3.8
Python 3.8.13 (default, May 14 2022, 10:07:39)
[Clang 13.0.0 (git@github.com:llvm/llvm-project.git llvmorg-13.0.0-0-gd7b669b3a on freebsd13
Type "help", "copyright", "credits" or "license" for more information.
>>> import psutil
>>> psutil.virtual_memory().total
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.8/site-packages/psutil/__init__.py", line 1968, in virtual_memory
ret = _psplatform.virtual_memory()
File "/usr/local/lib/python3.8/site-packages/psutil/_psbsd.py", line 181, in virtual_memory
mem = cext.virtual_mem()
OSError: [Errno 12] Cannot allocate memory (originated from sysctlbyname('vfs.bufspace'))
The problem is that the test at
psutil/psutil/arch/freebsd/mem.c
Line 33 in 5ca6870
<osreldate.h>
, hence __FreeBSD_version
is undefined (defaulting to 0), meaning that buffers
defaults to int
, whereas it should be long
for recent FreeBSD versions.
I checked this by taking the compilation command:
cc -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -O2 -pipe -march=znver1 -fstack-protector-strong -fno-strict-aliasing -O2 -pipe -march=znver1 -fstack-protector-strong -fno-strict-aliasing -fPIC -DPSUTIL_POSIX=1 -DPSUTIL_BSD=1 -DPSUTIL_SIZEOF_PID_T=4 -DPSUTIL_VERSION=591 -DPSUTIL_FREEBSD=1 -I/usr/local/include/python3.8 -c psutil/arch/freebsd/mem.c -o build/temp.freebsd-13.1-STABLE-amd64-cpython-38/psutil/arch/freebsd/mem.o
and converting it to just preprocess (-E -dD
instead of -c -o ...
), which generates (in part):
# 18 "psutil/arch/freebsd/mem.c" 2
PyObject *
psutil_virtual_mem(PyObject *self, PyObject *args) {
unsigned long total;
unsigned int active, inactive, wired, cached, free;
size_t size = sizeof(total);
struct vmtotal vm;
int mib[] = {2, 1};
long pagesize = psutil_getpagesize();
int buffers;
size_t buffers_size = sizeof(buffers);
note the int buffers;
. This works for a GENERIC kernel because that includes COMPAT_FREEBSD7
, which means that either int
or long
is accepted. (The sysctl vfs.bufspace
is defined at https://cgit.freebsd.org/src/tree/sys/kern/vfs_bio.c?h=stable/13#n208 and the implementation beginning at https://cgit.freebsd.org/src/tree/sys/kern/vfs_bio.c?h=stable/13#n469 tests whether COMPAT_FREEBSD7
is defined).
Searching through the code, there's no include of <osreldate.h>
anywhere so I suspect none of the __FreeBSD_version
tests work as intended.