summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2017-11-14 23:48:37 +0100
committerGiampaolo Rodola <g.rodola@gmail.com>2017-11-14 23:48:37 +0100
commit845e57ebe94c0f168c4446136f4824aa626a523f (patch)
tree8f54feb949795f37a8ec55f0cdfe943371460b85
parentc907d406d96f4c79a28e1a999e3d9ddc4888653e (diff)
parent26c77800591a09718064d3bcea4b04c9a8544dd1 (diff)
downloadpsutil-845e57ebe94c0f168c4446136f4824aa626a523f.tar.gz
Merge branch 'master' of github.com:giampaolo/psutil
-rw-r--r--HISTORY.rst5
-rw-r--r--Makefile2
-rw-r--r--appveyor.yml2
-rw-r--r--docs/index.rst23
-rw-r--r--psutil/_psutil_bsd.c2
-rw-r--r--psutil/_psutil_common.c17
-rw-r--r--psutil/_psutil_common.h2
-rw-r--r--psutil/_psutil_osx.c13
-rw-r--r--psutil/_psutil_posix.c13
-rw-r--r--psutil/_psutil_windows.c8
-rw-r--r--psutil/arch/freebsd/proc_socks.c2
-rw-r--r--psutil/arch/freebsd/specific.c6
-rw-r--r--psutil/arch/netbsd/specific.c2
-rw-r--r--psutil/arch/openbsd/specific.c4
-rw-r--r--psutil/arch/osx/process_info.c2
-rwxr-xr-xscripts/internal/winmake.py1
16 files changed, 82 insertions, 22 deletions
diff --git a/HISTORY.rst b/HISTORY.rst
index 48adbe52..6dadb031 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -5,6 +5,11 @@
*XXXX-XX-XX*
+**Enhancements**
+
+- 1173_: introduced PSUTIL_DEBUG environment variable which can be set in order
+ to print useful debug messages on stderr (useful in case of nasty errors).
+
**Bug fixes**
- 1152_: [Windows] disk_io_counters() may return an empty dict.
diff --git a/Makefile b/Makefile
index e8ff51ca..7b2eca86 100644
--- a/Makefile
+++ b/Makefile
@@ -26,7 +26,7 @@ DEPS = \
# In not in a virtualenv, add --user options for install commands.
INSTALL_OPTS = `$(PYTHON) -c "import sys; print('' if hasattr(sys, 'real_prefix') else '--user')"`
-TEST_PREFIX = PYTHONWARNINGS=all PSUTIL_TESTING=1
+TEST_PREFIX = PYTHONWARNINGS=all PSUTIL_TESTING=1 PSUTIL_DEBUG=1
all: test
diff --git a/appveyor.yml b/appveyor.yml
index f17b5b87..092dc23a 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -83,7 +83,7 @@ build: off
test_script:
- "%WITH_COMPILER% %PYTHON%/python -V"
- - "set PYTHONWARNINGS=all && set PSUTIL_TESTING=1 && %WITH_COMPILER% %PYTHON%/python psutil/tests/__main__.py"
+ - "set PYTHONWARNINGS=all && set PSUTIL_TESTING=1 && set PSUTIL_DEBUG=1 && %WITH_COMPILER% %PYTHON%/python psutil/tests/__main__.py"
after_test:
- "%WITH_COMPILER% %PYTHON%/python setup.py bdist_wheel"
diff --git a/docs/index.rst b/docs/index.rst
index ce798e92..620fea46 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -2300,6 +2300,29 @@ Constants
----
+Debug mode
+==========
+
+In case you bump into nasty errors which look like being psutil's fault you may
+want to run psutil in debug mode. psutil may (or may not) print some useful
+message on stderr before crashing with an exception
+(see `original motivation <https://github.com/giampaolo/psutil/issues/1173>`__).
+To enable debug mode on UNIX:
+
+.. code-block:: bash
+
+ PSUTIL_DEBUG=1 python script.py
+
+On Windows:
+
+.. code-block:: bat
+
+ set PSUTIL_DEBUG=1 && C:\python36\python.exe script.py
+
+.. versionadded:: 5.4.2
+
+----
+
Unicode
=======
diff --git a/psutil/_psutil_bsd.c b/psutil/_psutil_bsd.c
index f1adb1d3..9a2ed04b 100644
--- a/psutil/_psutil_bsd.c
+++ b/psutil/_psutil_bsd.c
@@ -475,7 +475,7 @@ psutil_proc_open_files(PyObject *self, PyObject *args) {
errno = 0;
freep = kinfo_getfile(pid, &cnt);
if (freep == NULL) {
- psutil_raise_for_pid(pid, "kinfo_getfile() failed");
+ psutil_raise_for_pid(pid, "kinfo_getfile()");
goto error;
}
diff --git a/psutil/_psutil_common.c b/psutil/_psutil_common.c
index cf9899f1..e9fce85e 100644
--- a/psutil/_psutil_common.c
+++ b/psutil/_psutil_common.c
@@ -11,6 +11,7 @@
// Global vars.
+int PSUTIL_DEBUG = 0;
int PSUTIL_TESTING = 0;
@@ -76,10 +77,26 @@ psutil_set_testing(PyObject *self, PyObject *args) {
/*
+ * Print a debug message on stderr. No-op if PSUTIL_DEBUG env var is not set.
+ */
+void
+psutil_debug(const char* format, ...) {
+ va_list argptr;
+ va_start(argptr, format);
+ fprintf(stderr, "psutil-dubug> ");
+ vfprintf(stderr, format, argptr);
+ fprintf(stderr, "\n");
+ va_end(argptr);
+}
+
+
+/*
* Called on module import on all platforms.
*/
void
psutil_setup(void) {
+ if (getenv("PSUTIL_DEBUG") != NULL)
+ PSUTIL_DEBUG = 1;
if (getenv("PSUTIL_TESTING") != NULL)
PSUTIL_TESTING = 1;
}
diff --git a/psutil/_psutil_common.h b/psutil/_psutil_common.h
index a609b886..965966af 100644
--- a/psutil/_psutil_common.h
+++ b/psutil/_psutil_common.h
@@ -7,6 +7,7 @@
#include <Python.h>
extern int PSUTIL_TESTING;
+extern int PSUTIL_DEBUG;
// a signaler for connections without an actual status
static const int PSUTIL_CONN_NONE = 128;
@@ -20,4 +21,5 @@ PyObject* AccessDenied(void);
PyObject* NoSuchProcess(void);
PyObject* psutil_set_testing(PyObject *self, PyObject *args);
+void psutil_debug(const char* format, ...);
void psutil_setup(void);
diff --git a/psutil/_psutil_osx.c b/psutil/_psutil_osx.c
index 4ff301d4..bb98c1cc 100644
--- a/psutil/_psutil_osx.c
+++ b/psutil/_psutil_osx.c
@@ -266,7 +266,7 @@ psutil_proc_exe(PyObject *self, PyObject *args) {
if (pid == 0)
AccessDenied();
else
- psutil_raise_for_pid(pid, "proc_pidpath() syscall failed");
+ psutil_raise_for_pid(pid, "proc_pidpath()");
return NULL;
}
return PyUnicode_DecodeFSDefault(buf);
@@ -336,7 +336,7 @@ psutil_proc_memory_maps(PyObject *self, PyObject *args) {
err = task_for_pid(mach_task_self(), (pid_t)pid, &task);
if (err != KERN_SUCCESS) {
- psutil_raise_for_pid(pid, "task_for_pid() failed");
+ psutil_raise_for_pid(pid, "task_for_pid()");
goto error;
}
@@ -376,8 +376,7 @@ psutil_proc_memory_maps(PyObject *self, PyObject *args) {
errno = 0;
proc_regionfilename((pid_t)pid, address, buf, sizeof(buf));
if ((errno != 0) || ((sizeof(buf)) <= 0)) {
- psutil_raise_for_pid(
- pid, "proc_regionfilename() syscall failed");
+ psutil_raise_for_pid(pid, "proc_regionfilename()");
goto error;
}
@@ -1147,7 +1146,8 @@ psutil_proc_open_files(PyObject *self, PyObject *args) {
continue;
}
else {
- psutil_raise_for_pid(pid, "proc_pidinfo() syscall failed");
+ psutil_raise_for_pid(
+ pid, "proc_pidinfo(PROC_PIDFDVNODEPATHINFO)");
goto error;
}
}
@@ -1259,7 +1259,8 @@ psutil_proc_connections(PyObject *self, PyObject *args) {
continue;
}
else {
- psutil_raise_for_pid(pid, "proc_pidinfo() syscall failed");
+ psutil_raise_for_pid(
+ pid, "proc_pidinfo(PROC_PIDFDSOCKETINFO)");
goto error;
}
}
diff --git a/psutil/_psutil_posix.c b/psutil/_psutil_posix.c
index ea0fba53..76cf2db0 100644
--- a/psutil/_psutil_posix.c
+++ b/psutil/_psutil_posix.c
@@ -112,16 +112,21 @@ psutil_pid_exists(long pid) {
* This will always set a Python exception and return NULL.
*/
int
-psutil_raise_for_pid(long pid, char *msg) {
+psutil_raise_for_pid(long pid, char *syscall_name) {
// Set exception to AccessDenied if pid exists else NoSuchProcess.
if (errno != 0) {
+ // Unlikely we get here.
PyErr_SetFromErrno(PyExc_OSError);
return 0;
}
- if (psutil_pid_exists(pid) == 0)
+ else if (psutil_pid_exists(pid) == 0) {
+ psutil_debug("%s syscall failed and PID %i no longer exists; "
+ "assume NoSuchProcess", syscall_name, pid);
NoSuchProcess();
- else
- PyErr_SetString(PyExc_RuntimeError, msg);
+ }
+ else {
+ PyErr_Format(PyExc_RuntimeError, "%s syscall failed", syscall_name);
+ }
return 0;
}
diff --git a/psutil/_psutil_windows.c b/psutil/_psutil_windows.c
index 82ad26b7..1f757385 100644
--- a/psutil/_psutil_windows.c
+++ b/psutil/_psutil_windows.c
@@ -341,6 +341,8 @@ psutil_proc_kill(PyObject *self, PyObject *args) {
if (hProcess == NULL) {
if (GetLastError() == ERROR_INVALID_PARAMETER) {
// see https://github.com/giampaolo/psutil/issues/24
+ psutil_debug("OpenProcess -> ERROR_INVALID_PARAMETER turned "
+ "into NoSuchProcess");
NoSuchProcess();
}
else {
@@ -2405,10 +2407,14 @@ psutil_disk_io_counters(PyObject *self, PyObject *args) {
// 1364/job/ascpdi271b06jle3
// Assume it means we're dealing with some exotic disk
// and go on.
+ psutil_debug("DeviceIoControl -> ERROR_INVALID_FUNCTION; "
+ "ignore PhysicalDrive%i", devNum);
goto next;
}
else if (GetLastError() == ERROR_NOT_SUPPORTED) {
// Again, let's assume we're dealing with some exotic disk.
+ psutil_debug("DeviceIoControl -> ERROR_NOT_SUPPORTED; "
+ "ignore PhysicalDrive%i", devNum);
goto next;
}
// XXX: it seems we should also catch ERROR_INVALID_PARAMETER:
@@ -2423,7 +2429,7 @@ psutil_disk_io_counters(PyObject *self, PyObject *args) {
goto error;
}
- sprintf_s(szDeviceDisplay, MAX_PATH, "PhysicalDrive%d", devNum);
+ sprintf_s(szDeviceDisplay, MAX_PATH, "PhysicalDrive%i", devNum);
py_tuple = Py_BuildValue(
"(IILLKK)",
diskPerformance.ReadCount,
diff --git a/psutil/arch/freebsd/proc_socks.c b/psutil/arch/freebsd/proc_socks.c
index c5b19a0d..a458a01e 100644
--- a/psutil/arch/freebsd/proc_socks.c
+++ b/psutil/arch/freebsd/proc_socks.c
@@ -212,7 +212,7 @@ psutil_proc_connections(PyObject *self, PyObject *args) {
errno = 0;
freep = kinfo_getfile(pid, &cnt);
if (freep == NULL) {
- psutil_raise_for_pid(pid, "kinfo_getfile() failed");
+ psutil_raise_for_pid(pid, "kinfo_getfile()");
goto error;
}
diff --git a/psutil/arch/freebsd/specific.c b/psutil/arch/freebsd/specific.c
index 8d09ad89..ff128e65 100644
--- a/psutil/arch/freebsd/specific.c
+++ b/psutil/arch/freebsd/specific.c
@@ -548,7 +548,7 @@ psutil_proc_cwd(PyObject *self, PyObject *args) {
errno = 0;
freep = kinfo_getfile(pid, &cnt);
if (freep == NULL) {
- psutil_raise_for_pid(pid, "kinfo_getfile() failed");
+ psutil_raise_for_pid(pid, "kinfo_getfile()");
goto error;
}
@@ -597,7 +597,7 @@ psutil_proc_num_fds(PyObject *self, PyObject *args) {
errno = 0;
freep = kinfo_getfile(pid, &cnt);
if (freep == NULL) {
- psutil_raise_for_pid(pid, "kinfo_getfile() failed");
+ psutil_raise_for_pid(pid, "kinfo_getfile()");
return NULL;
}
free(freep);
@@ -765,7 +765,7 @@ psutil_proc_memory_maps(PyObject *self, PyObject *args) {
errno = 0;
freep = kinfo_getvmmap(pid, &cnt);
if (freep == NULL) {
- psutil_raise_for_pid(pid, "kinfo_getvmmap() failed");
+ psutil_raise_for_pid(pid, "kinfo_getvmmap()");
goto error;
}
for (i = 0; i < cnt; i++) {
diff --git a/psutil/arch/netbsd/specific.c b/psutil/arch/netbsd/specific.c
index 1dc2080e..0a32139d 100644
--- a/psutil/arch/netbsd/specific.c
+++ b/psutil/arch/netbsd/specific.c
@@ -502,7 +502,7 @@ psutil_proc_num_fds(PyObject *self, PyObject *args) {
errno = 0;
freep = kinfo_getfile(pid, &cnt);
if (freep == NULL) {
- psutil_raise_for_pid(pid, "kinfo_getfile() failed");
+ psutil_raise_for_pid(pid, "kinfo_getfile()");
return NULL;
}
free(freep);
diff --git a/psutil/arch/openbsd/specific.c b/psutil/arch/openbsd/specific.c
index de30c4d7..2a0d30ce 100644
--- a/psutil/arch/openbsd/specific.c
+++ b/psutil/arch/openbsd/specific.c
@@ -404,7 +404,7 @@ psutil_proc_num_fds(PyObject *self, PyObject *args) {
errno = 0;
freep = kinfo_getfile(pid, &cnt);
if (freep == NULL) {
- psutil_raise_for_pid(pid, "kinfo_getfile() failed");
+ psutil_raise_for_pid(pid, "kinfo_getfile()");
return NULL;
}
free(freep);
@@ -509,7 +509,7 @@ psutil_proc_connections(PyObject *self, PyObject *args) {
errno = 0;
freep = kinfo_getfile(pid, &cnt);
if (freep == NULL) {
- psutil_raise_for_pid(pid, "kinfo_getfile() failed");
+ psutil_raise_for_pid(pid, "kinfo_getfile()");
goto error;
}
diff --git a/psutil/arch/osx/process_info.c b/psutil/arch/osx/process_info.c
index 7c715be8..f0a01132 100644
--- a/psutil/arch/osx/process_info.c
+++ b/psutil/arch/osx/process_info.c
@@ -354,7 +354,7 @@ psutil_proc_pidinfo(long pid, int flavor, uint64_t arg, void *pti, int size) {
errno = 0;
int ret = proc_pidinfo((int)pid, flavor, arg, pti, size);
if ((ret <= 0) || ((unsigned long)ret < sizeof(pti))) {
- psutil_raise_for_pid(pid, "proc_pidinfo() syscall failed");
+ psutil_raise_for_pid(pid, "proc_pidinfo()");
return 0;
}
return ret;
diff --git a/scripts/internal/winmake.py b/scripts/internal/winmake.py
index 35ce059c..548f7a8e 100755
--- a/scripts/internal/winmake.py
+++ b/scripts/internal/winmake.py
@@ -177,6 +177,7 @@ def recursive_rm(*patterns):
def test_setup():
os.environ['PYTHONWARNINGS'] = 'all'
os.environ['PSUTIL_TESTING'] = '1'
+ os.environ['PSUTIL_DEBUG'] = '1'
# ===================================================================