Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1173 debug mode #1176

Merged
merged 14 commits into from
Nov 14, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
23 changes: 23 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
=======

Expand Down
2 changes: 1 addition & 1 deletion psutil/_psutil_bsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
17 changes: 17 additions & 0 deletions psutil/_psutil_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@


// Global vars.
int PSUTIL_DEBUG = 0;
int PSUTIL_TESTING = 0;


Expand Down Expand Up @@ -75,11 +76,27 @@ 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;
}
2 changes: 2 additions & 0 deletions psutil/_psutil_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
13 changes: 7 additions & 6 deletions psutil/_psutil_osx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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;
}
}
Expand Down
13 changes: 9 additions & 4 deletions psutil/_psutil_posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
8 changes: 7 additions & 1 deletion psutil/_psutil_windows.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -2409,10 +2411,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:
Expand All @@ -2427,7 +2433,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,
Expand Down
2 changes: 1 addition & 1 deletion psutil/arch/freebsd/proc_socks.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
6 changes: 3 additions & 3 deletions psutil/arch/freebsd/specific.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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++) {
Expand Down
2 changes: 1 addition & 1 deletion psutil/arch/netbsd/specific.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions psutil/arch/openbsd/specific.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion psutil/arch/osx/process_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions scripts/internal/winmake.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'


# ===================================================================
Expand Down