Skip to content

[FreeBSD] psutil.virtual_memory() fails without COMPAT_FREEBSD7 in the kernel #2113

Closed
@peterjeremy

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

#if __FreeBSD_version > 702101
occurs without previously including <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.

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions