Skip to content

Commit c93b521

Browse files
committed
Windows: Fallback to powershell if fiddle is not loadable
1 parent b92db45 commit c93b521

1 file changed

Lines changed: 60 additions & 40 deletions

File tree

tool/lib/memory_status.rb

Lines changed: 60 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -20,48 +20,68 @@ def self.read_status
2020
data.scan(pat) {|k, v| keys << k.downcase.intern}
2121

2222
when /mswin|mingw/ =~ RUBY_PLATFORM
23-
require 'fiddle/import'
24-
require 'fiddle/types'
25-
26-
module Win32
27-
extend Fiddle::Importer
28-
dlload "kernel32.dll", "psapi.dll"
29-
include Fiddle::Win32Types
30-
typealias "SIZE_T", "size_t"
31-
32-
PROCESS_MEMORY_COUNTERS = struct [
33-
"DWORD cb",
34-
"DWORD PageFaultCount",
35-
"SIZE_T PeakWorkingSetSize",
36-
"SIZE_T WorkingSetSize",
37-
"SIZE_T QuotaPeakPagedPoolUsage",
38-
"SIZE_T QuotaPagedPoolUsage",
39-
"SIZE_T QuotaPeakNonPagedPoolUsage",
40-
"SIZE_T QuotaNonPagedPoolUsage",
41-
"SIZE_T PagefileUsage",
42-
"SIZE_T PeakPagefileUsage",
43-
]
44-
45-
typealias "PPROCESS_MEMORY_COUNTERS", "PROCESS_MEMORY_COUNTERS*"
46-
47-
extern "HANDLE GetCurrentProcess()", :stdcall
48-
extern "BOOL GetProcessMemoryInfo(HANDLE, PPROCESS_MEMORY_COUNTERS, DWORD)", :stdcall
49-
50-
module_function
51-
def memory_info
52-
size = PROCESS_MEMORY_COUNTERS.size
53-
data = PROCESS_MEMORY_COUNTERS.malloc
54-
data.cb = size
55-
data if GetProcessMemoryInfo(GetCurrentProcess(), data, size)
23+
keys.push(:size, :rss, :peak)
24+
25+
begin
26+
require 'fiddle/import'
27+
require 'fiddle/types'
28+
rescue LoadError
29+
# Fallback to PowerShell command to get memory information for current process
30+
def self.read_status
31+
cmd = [
32+
"powershell.exe", "-NoProfile", "-Command",
33+
"Get-Process -Id #{$$} | " \
34+
"% { Write-Output $_.PagedMemorySize64 $_.WorkingSet64 $_.PeakWorkingSet64 }"
35+
]
36+
37+
IO.popen(cmd, "r", err: [:child, :out]) do |out|
38+
if /^(\d+)\n(\d+)\n(\d+)$/ =~ out.read
39+
yield :size, $1.to_i
40+
yield :rss, $2.to_i
41+
yield :peak, $3.to_i
42+
end
43+
end
44+
end
45+
else
46+
module Win32
47+
extend Fiddle::Importer
48+
dlload "kernel32.dll", "psapi.dll"
49+
include Fiddle::Win32Types
50+
typealias "SIZE_T", "size_t"
51+
52+
PROCESS_MEMORY_COUNTERS = struct [
53+
"DWORD cb",
54+
"DWORD PageFaultCount",
55+
"SIZE_T PeakWorkingSetSize",
56+
"SIZE_T WorkingSetSize",
57+
"SIZE_T QuotaPeakPagedPoolUsage",
58+
"SIZE_T QuotaPagedPoolUsage",
59+
"SIZE_T QuotaPeakNonPagedPoolUsage",
60+
"SIZE_T QuotaNonPagedPoolUsage",
61+
"SIZE_T PagefileUsage",
62+
"SIZE_T PeakPagefileUsage",
63+
]
64+
65+
typealias "PPROCESS_MEMORY_COUNTERS", "PROCESS_MEMORY_COUNTERS*"
66+
67+
extern "HANDLE GetCurrentProcess()", :stdcall
68+
extern "BOOL GetProcessMemoryInfo(HANDLE, PPROCESS_MEMORY_COUNTERS, DWORD)", :stdcall
69+
70+
module_function
71+
def memory_info
72+
size = PROCESS_MEMORY_COUNTERS.size
73+
data = PROCESS_MEMORY_COUNTERS.malloc
74+
data.cb = size
75+
data if GetProcessMemoryInfo(GetCurrentProcess(), data, size)
76+
end
5677
end
57-
end
5878

59-
keys.push(:size, :rss, :peak)
60-
def self.read_status
61-
if info = Win32.memory_info
62-
yield :size, info.PagefileUsage
63-
yield :rss, info.WorkingSetSize
64-
yield :peak, info.PeakWorkingSetSize
79+
def self.read_status
80+
if info = Win32.memory_info
81+
yield :size, info.PagefileUsage
82+
yield :rss, info.WorkingSetSize
83+
yield :peak, info.PeakWorkingSetSize
84+
end
6585
end
6686
end
6787
when (require_relative 'find_executable'

0 commit comments

Comments
 (0)