summaryrefslogtreecommitdiff
path: root/psutil
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2022-09-02 11:38:20 +0000
committerGiampaolo Rodola <g.rodola@gmail.com>2022-09-02 11:39:08 +0000
commitc7c7bbcfc762d73a50d3cb2ad6f277dad7bb9a6b (patch)
treeecc034b178f6a9d3f89fab6ccec45e9bd018aff2 /psutil
parentd2fab7c8de16b6ffbfb0faa3e832845bc1ef0df0 (diff)
downloadpsutil-c7c7bbcfc762d73a50d3cb2ad6f277dad7bb9a6b.tar.gz
FreeBSD / pids(): increase buf size if not enough
...dynamically, in case of ENOMEM, instead of crashing. Fixes #2093.
Diffstat (limited to 'psutil')
-rw-r--r--psutil/arch/freebsd/proc.c43
1 files changed, 30 insertions, 13 deletions
diff --git a/psutil/arch/freebsd/proc.c b/psutil/arch/freebsd/proc.c
index a2e130b5..214dbc48 100644
--- a/psutil/arch/freebsd/proc.c
+++ b/psutil/arch/freebsd/proc.c
@@ -83,6 +83,7 @@ psutil_get_proc_list(struct kinfo_proc **procList, size_t *procCount) {
struct kinfo_proc *buf = NULL;
int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_PROC, 0 };
size_t length = 0;
+ size_t max_length = 12 * 1024 * 1024; // 12MB
assert(procList != NULL);
assert(*procList == NULL);
@@ -95,20 +96,36 @@ psutil_get_proc_list(struct kinfo_proc **procList, size_t *procCount) {
return 1;
}
- // Allocate an appropriately sized buffer based on the results
- // from the previous call.
- buf = malloc(length);
- if (buf == NULL) {
- PyErr_NoMemory();
- return 1;
- }
+ while (1) {
+ // Allocate an appropriately sized buffer based on the results
+ // from the previous call.
+ buf = malloc(length);
+ if (buf == NULL) {
+ PyErr_NoMemory();
+ return 1;
+ }
- // Call sysctl again with the new buffer.
- err = sysctl(name, 3, buf, &length, NULL, 0);
- if (err == -1) {
- PyErr_SetFromOSErrnoWithSyscall("sysctl");
- free(buf);
- return 1;
+ // Call sysctl again with the new buffer.
+ err = sysctl(name, 3, buf, &length, NULL, 0);
+ if (err == -1) {
+ free(buf);
+ if (errno == ENOMEM) {
+ // Sometimes the first sysctl() suggested size is not enough,
+ // so we dynamically increase it until it's big enough :
+ // https://github.com/giampaolo/psutil/issues/2093
+ psutil_debug("errno=ENOMEM, length=%zu; retrying", length);
+ length *= 2;
+ if (length < max_length) {
+ continue;
+ }
+ }
+
+ PyErr_SetFromOSErrnoWithSyscall("sysctl()");
+ return 1;
+ }
+ else {
+ break;
+ }
}
*procList = buf;