summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2020-10-31 15:37:31 +0100
committerGitHub <noreply@github.com>2020-10-31 15:37:31 +0100
commit9aba2efe6cee0a343002d0453674aca68a7b7aec (patch)
tree2b0b95c7711bcba4f3911ea44b9d9846a18380d4
parent40abe5c0aa3e258161284b58cedcee1e11a66e75 (diff)
downloadpsutil-9aba2efe6cee0a343002d0453674aca68a7b7aec.tar.gz
Fix py 3.9 [WinError 998] Invalid access to memory location (#1866)
-rw-r--r--README.rst4
-rw-r--r--appveyor.yml19
-rw-r--r--psutil/_psutil_common.c7
-rw-r--r--psutil/_psutil_common.h8
-rw-r--r--psutil/arch/windows/process_info.c72
-rwxr-xr-xpsutil/tests/test_contracts.py5
-rwxr-xr-xpsutil/tests/test_misc.py3
-rwxr-xr-xscripts/internal/download_wheels_appveyor.py2
-rwxr-xr-xscripts/internal/winmake.py29
-rwxr-xr-xscripts/netstat.py3
10 files changed, 105 insertions, 47 deletions
diff --git a/README.rst b/README.rst
index 3b28ee5c..4095a3c5 100644
--- a/README.rst
+++ b/README.rst
@@ -225,7 +225,7 @@ Network
{'eth0': netio(bytes_sent=485291293, bytes_recv=6004858642, packets_sent=3251564, packets_recv=4787798, errin=0, errout=0, dropin=0, dropout=0),
'lo': netio(bytes_sent=2838627, bytes_recv=2838627, packets_sent=30567, packets_recv=30567, errin=0, errout=0, dropin=0, dropout=0)}
>>>
- >>> psutil.net_connections()
+ >>> psutil.net_connections(kind='tcp')
[sconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=48776), raddr=addr(ip='93.186.135.91', port=80), status='ESTABLISHED', pid=1254),
sconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=43761), raddr=addr(ip='72.14.234.100', port=80), status='CLOSING', pid=2987),
...]
@@ -359,7 +359,7 @@ Process management
[popenfile(path='/home/giampaolo/monit.py', fd=3, position=0, mode='r', flags=32768),
popenfile(path='/var/log/monit.log', fd=4, position=235542, mode='a', flags=33793)]
>>>
- >>> p.connections()
+ >>> p.connections(kind='tcp')
[pconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=48776), raddr=addr(ip='93.186.135.91', port=80), status='ESTABLISHED'),
pconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=43761), raddr=addr(ip='72.14.234.100', port=80), status='CLOSING')]
>>>
diff --git a/appveyor.yml b/appveyor.yml
index e0912a1e..ff9d35b9 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -15,10 +15,6 @@ environment:
PYTHON_VERSION: "2.7.x"
PYTHON_ARCH: "32"
- - PYTHON: "C:\\Python35"
- PYTHON_VERSION: "3.5.x"
- PYTHON_ARCH: "32"
-
- PYTHON: "C:\\Python36"
PYTHON_VERSION: "3.6.x"
PYTHON_ARCH: "32"
@@ -31,16 +27,17 @@ environment:
PYTHON_VERSION: "3.8.x"
PYTHON_ARCH: "32"
+ - PYTHON: "C:\\Python39"
+ PYTHON_VERSION: "3.9.x"
+ APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
+ PYTHON_ARCH: "32"
+
# 64 bits
- PYTHON: "C:\\Python27-x64"
PYTHON_VERSION: "2.7.x"
PYTHON_ARCH: "64"
- - PYTHON: "C:\\Python35-x64"
- PYTHON_VERSION: "3.5.x"
- PYTHON_ARCH: "64"
-
- PYTHON: "C:\\Python36-x64"
PYTHON_VERSION: "3.6.x"
PYTHON_ARCH: "64"
@@ -53,6 +50,11 @@ environment:
PYTHON_VERSION: "3.8.x"
PYTHON_ARCH: "64"
+ - PYTHON: "C:\\Python39-x64"
+ PYTHON_VERSION: "3.9.x"
+ APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
+ PYTHON_ARCH: "64"
+
init:
- "ECHO %PYTHON% %PYTHON_VERSION% %PYTHON_ARCH%"
@@ -103,3 +105,4 @@ only_commits:
- psutil/tests/*
- scripts/*
- setup.py
+
diff --git a/psutil/_psutil_common.c b/psutil/_psutil_common.c
index f821aba3..4178e0c0 100644
--- a/psutil/_psutil_common.c
+++ b/psutil/_psutil_common.c
@@ -199,13 +199,6 @@ int PSUTIL_WINVER;
SYSTEM_INFO PSUTIL_SYSTEM_INFO;
CRITICAL_SECTION PSUTIL_CRITICAL_SECTION;
-#define NT_FACILITY_MASK 0xfff
-#define NT_FACILITY_SHIFT 16
-#define NT_FACILITY(Status) \
- ((((ULONG)(Status)) >> NT_FACILITY_SHIFT) & NT_FACILITY_MASK)
-#define NT_NTWIN32(status) (NT_FACILITY(Status) == FACILITY_WIN32)
-#define WIN32_FROM_NTSTATUS(Status) (((ULONG)(Status)) & 0xffff)
-
// A wrapper around GetModuleHandle and GetProcAddress.
PVOID
diff --git a/psutil/_psutil_common.h b/psutil/_psutil_common.h
index 3162772e..cb0b399d 100644
--- a/psutil/_psutil_common.h
+++ b/psutil/_psutil_common.h
@@ -134,6 +134,14 @@ void convert_kvm_err(const char *syscall, char *errbuf);
#define MALLOC_ZERO(x) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
+ #define _NT_FACILITY_MASK 0xfff
+ #define _NT_FACILITY_SHIFT 16
+ #define _NT_FACILITY(status) \
+ ((((ULONG)(status)) >> _NT_FACILITY_SHIFT) & _NT_FACILITY_MASK)
+
+ #define NT_NTWIN32(status) (_NT_FACILITY(status) == FACILITY_WIN32)
+ #define WIN32_FROM_NTSTATUS(status) (((ULONG)(status)) & 0xffff)
+
#define LO_T 1e-7
#define HI_T 429.4967296
diff --git a/psutil/arch/windows/process_info.c b/psutil/arch/windows/process_info.c
index 73a69912..36283add 100644
--- a/psutil/arch/windows/process_info.c
+++ b/psutil/arch/windows/process_info.c
@@ -50,6 +50,36 @@ enum psutil_process_data_kind {
};
+static void
+psutil_convert_winerr(ULONG err, char* syscall) {
+ char fullmsg[8192];
+
+ if (err == ERROR_NOACCESS) {
+ sprintf(
+ fullmsg,
+ "(originated from %s -> ERROR_NOACCESS; converted to AccessDenied)",
+ syscall);
+ psutil_debug(fullmsg);
+ AccessDenied(fullmsg);
+ }
+ else {
+ PyErr_SetFromOSErrnoWithSyscall(syscall);
+ }
+}
+
+
+static void
+psutil_convert_ntstatus_err(NTSTATUS status, char* syscall) {
+ ULONG err;
+
+ if (NT_NTWIN32(status))
+ err = WIN32_FROM_NTSTATUS(status);
+ else
+ err = RtlNtStatusToDosErrorNoTeb(status);
+ psutil_convert_winerr(err, syscall);
+}
+
+
/*
* Get data from the process with the given pid. The data is returned
* in the pdata output member as a nul terminated string which must be
@@ -87,16 +117,14 @@ psutil_get_process_data(DWORD pid,
http://www.drdobbs.com/embracing-64-bit-windows/184401966
*/
SIZE_T size = 0;
-#ifndef _WIN64
- static __NtQueryInformationProcess NtWow64QueryInformationProcess64 = NULL;
- static _NtWow64ReadVirtualMemory64 NtWow64ReadVirtualMemory64 = NULL;
-#endif
HANDLE hProcess = NULL;
LPCVOID src;
WCHAR *buffer = NULL;
#ifdef _WIN64
LPVOID ppeb32 = NULL;
#else
+ static __NtQueryInformationProcess NtWow64QueryInformationProcess64 = NULL;
+ static _NtWow64ReadVirtualMemory64 NtWow64ReadVirtualMemory64 = NULL;
PVOID64 src64;
BOOL weAreWow64;
BOOL theyAreWow64;
@@ -133,7 +161,7 @@ psutil_get_process_data(DWORD pid,
if (!ReadProcessMemory(hProcess, ppeb32, &peb32, sizeof(peb32), NULL)) {
// May fail with ERROR_PARTIAL_COPY, see:
// https://github.com/giampaolo/psutil/issues/875
- PyErr_SetFromWindowsErr(0);
+ psutil_convert_winerr(GetLastError(), "ReadProcessMemory");
goto error;
}
@@ -146,7 +174,7 @@ psutil_get_process_data(DWORD pid,
{
// May fail with ERROR_PARTIAL_COPY, see:
// https://github.com/giampaolo/psutil/issues/875
- PyErr_SetFromWindowsErr(0);
+ psutil_convert_winerr(GetLastError(), "ReadProcessMemory");
goto error;
}
@@ -164,7 +192,7 @@ psutil_get_process_data(DWORD pid,
break;
}
} else
-#else
+#else // #ifdef _WIN64
/* 32 bit case. Check if the target is also 32 bit. */
if (!IsWow64Process(GetCurrentProcess(), &weAreWow64) ||
!IsWow64Process(hProcess, &theyAreWow64)) {
@@ -206,10 +234,9 @@ psutil_get_process_data(DWORD pid,
sizeof(pbi64),
NULL);
if (!NT_SUCCESS(status)) {
- psutil_SetFromNTStatusErr(
- status,
- "NtWow64QueryInformationProcess64(ProcessBasicInformation)"
- );
+ psutil_convert_ntstatus_err(
+ status,
+ "NtWow64QueryInformationProcess64(ProcessBasicInformation)");
goto error;
}
@@ -221,7 +248,8 @@ psutil_get_process_data(DWORD pid,
sizeof(peb64),
NULL);
if (!NT_SUCCESS(status)) {
- psutil_SetFromNTStatusErr(status, "NtWow64ReadVirtualMemory64");
+ psutil_convert_ntstatus_err(
+ status, "NtWow64ReadVirtualMemory64(pbi64.PebBaseAddress)");
goto error;
}
@@ -233,10 +261,8 @@ psutil_get_process_data(DWORD pid,
sizeof(procParameters64),
NULL);
if (!NT_SUCCESS(status)) {
- psutil_SetFromNTStatusErr(
- status,
- "NtWow64ReadVirtualMemory64(ProcessParameters)"
- );
+ psutil_convert_ntstatus_err(
+ status, "NtWow64ReadVirtualMemory64(peb64.ProcessParameters)");
goto error;
}
@@ -284,7 +310,7 @@ psutil_get_process_data(DWORD pid,
{
// May fail with ERROR_PARTIAL_COPY, see:
// https://github.com/giampaolo/psutil/issues/875
- PyErr_SetFromWindowsErr(0);
+ psutil_convert_winerr(GetLastError(), "ReadProcessMemory");
goto error;
}
@@ -297,7 +323,7 @@ psutil_get_process_data(DWORD pid,
{
// May fail with ERROR_PARTIAL_COPY, see:
// https://github.com/giampaolo/psutil/issues/875
- PyErr_SetFromWindowsErr(0);
+ psutil_convert_winerr(GetLastError(), "ReadProcessMemory");
goto error;
}
@@ -343,7 +369,7 @@ psutil_get_process_data(DWORD pid,
size,
NULL);
if (!NT_SUCCESS(status)) {
- psutil_SetFromNTStatusErr(status, "NtWow64ReadVirtualMemory64");
+ psutil_convert_ntstatus_err(status, "NtWow64ReadVirtualMemory64");
goto error;
}
} else
@@ -351,7 +377,7 @@ psutil_get_process_data(DWORD pid,
if (!ReadProcessMemory(hProcess, src, buffer, size, NULL)) {
// May fail with ERROR_PARTIAL_COPY, see:
// https://github.com/giampaolo/psutil/issues/875
- PyErr_SetFromWindowsErr(0);
+ psutil_convert_winerr(GetLastError(), "ReadProcessMemory");
goto error;
}
@@ -698,16 +724,16 @@ psutil_proc_info(PyObject *self, PyObject *args) {
py_retlist = Py_BuildValue(
#if defined(_WIN64)
- "kkdddiKKKKKK" "kKKKKKKKKK",
+ "kkdddkKKKKKK" "kKKKKKKKKK",
#else
- "kkdddiKKKKKK" "kIIIIIIIII",
+ "kkdddkKKKKKK" "kIIIIIIIII",
#endif
process->HandleCount, // num handles
ctx_switches, // num ctx switches
user_time, // cpu user time
kernel_time, // cpu kernel time
create_time, // create time
- (int)process->NumberOfThreads, // num threads
+ process->NumberOfThreads, // num threads
// IO counters
process->ReadOperationCount.QuadPart, // io rcount
process->WriteOperationCount.QuadPart, // io wcount
diff --git a/psutil/tests/test_contracts.py b/psutil/tests/test_contracts.py
index 72fe8c0c..659dc018 100755
--- a/psutil/tests/test_contracts.py
+++ b/psutil/tests/test_contracts.py
@@ -32,6 +32,7 @@ from psutil import WINDOWS
from psutil._compat import FileNotFoundError
from psutil._compat import long
from psutil._compat import range
+from psutil.tests import APPVEYOR
from psutil.tests import create_sockets
from psutil.tests import enum
from psutil.tests import GITHUB_WHEELS
@@ -451,6 +452,8 @@ class TestFetchAllProcesses(PsutilTestCase):
def name(self, ret, info):
self.assertIsInstance(ret, str)
+ if APPVEYOR and not ret and info['status'] == 'stopped':
+ return
# on AIX, "<exiting>" processes don't have names
if not AIX:
assert ret
@@ -521,6 +524,8 @@ class TestFetchAllProcesses(PsutilTestCase):
def num_threads(self, ret, info):
self.assertIsInstance(ret, int)
+ if APPVEYOR and not ret and info['status'] == 'stopped':
+ return
self.assertGreaterEqual(ret, 1)
def threads(self, ret, info):
diff --git a/psutil/tests/test_misc.py b/psutil/tests/test_misc.py
index 8fcee12a..f4e1a5df 100755
--- a/psutil/tests/test_misc.py
+++ b/psutil/tests/test_misc.py
@@ -28,7 +28,6 @@ from psutil._common import wrap_numbers
from psutil._compat import PY3
from psutil.tests import APPVEYOR
from psutil.tests import CI_TESTING
-from psutil.tests import DEVNULL
from psutil.tests import HAS_BATTERY
from psutil.tests import HAS_MEMORY_MAPS
from psutil.tests import HAS_NET_IO_COUNTERS
@@ -719,7 +718,7 @@ class TestScripts(PsutilTestCase):
def test_procsmem(self):
if 'uss' not in psutil.Process().memory_full_info()._fields:
raise self.skipTest("not supported")
- self.assert_stdout('procsmem.py', stderr=DEVNULL)
+ self.assert_stdout('procsmem.py')
def test_killall(self):
self.assert_syntax('killall.py')
diff --git a/scripts/internal/download_wheels_appveyor.py b/scripts/internal/download_wheels_appveyor.py
index bbae2e94..a6773f34 100755
--- a/scripts/internal/download_wheels_appveyor.py
+++ b/scripts/internal/download_wheels_appveyor.py
@@ -25,7 +25,7 @@ from psutil._common import print_color
BASE_URL = 'https://ci.appveyor.com/api'
-PY_VERSIONS = ['2.7', '3.5', '3.6', '3.7', '3.8']
+PY_VERSIONS = ['2.7', '3.6', '3.7', '3.8', '3.9']
TIMEOUT = 30
diff --git a/scripts/internal/winmake.py b/scripts/internal/winmake.py
index 3d9d0a8d..faa2aea8 100755
--- a/scripts/internal/winmake.py
+++ b/scripts/internal/winmake.py
@@ -525,6 +525,12 @@ def print_api_speed():
sh("%s -Wa scripts\\internal\\print_api_speed.py" % PYTHON)
+def download_appveyor_wheels():
+ """Download appveyor wheels."""
+ sh("%s -Wa scripts\\internal\\download_wheels_appveyor.py "
+ "--user giampaolo --project psutil" % PYTHON)
+
+
def get_python(path):
if not path:
return sys.executable
@@ -532,9 +538,25 @@ def get_python(path):
return path
# try to look for a python installation given a shortcut name
path = path.replace('.', '')
- vers = ('26', '27', '36', '37', '38',
- '26-64', '27-64', '36-64', '37-64', '38-64'
- '26-32', '27-32', '36-32', '37-32', '38-32')
+ vers = (
+ '26',
+ '26-32',
+ '26-64',
+ '27',
+ '27-32',
+ '27-64',
+ '36',
+ '36-32',
+ '36-64',
+ '37',
+ '37-32',
+ '37-64',
+ '38',
+ '38-32',
+ '38-64',
+ '39-32',
+ '39-64',
+ )
for v in vers:
pypath = r'C:\\python%s\python.exe' % v
if path in pypath and os.path.isfile(pypath):
@@ -554,6 +576,7 @@ def main():
sp.add_parser('build', help="build")
sp.add_parser('clean', help="deletes dev files")
sp.add_parser('coverage', help="run coverage tests.")
+ sp.add_parser('download-appveyor-wheels', help="download wheels.")
sp.add_parser('help', help="print this help")
sp.add_parser('install', help="build + install in develop/edit mode")
sp.add_parser('install-git-hooks', help="install GIT pre-commit hook")
diff --git a/scripts/netstat.py b/scripts/netstat.py
index 5a21358e..1832a096 100755
--- a/scripts/netstat.py
+++ b/scripts/netstat.py
@@ -48,13 +48,14 @@ def main():
raddr = ""
if c.raddr:
raddr = "%s:%s" % (c.raddr)
+ name = proc_names.get(c.pid, '?') or ''
print(templ % (
proto_map[(c.family, c.type)],
laddr,
raddr or AD,
c.status,
c.pid or AD,
- proc_names.get(c.pid, '?')[:15],
+ name[:15],
))