Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

# 

# LSST Data Management System 

# 

# Copyright 2008-2017 AURA/LSST. 

# 

# This product includes software developed by the 

# LSST Project (http://www.lsst.org/). 

# 

# This program is free software: you can redistribute it and/or modify 

# it under the terms of the GNU General Public License as published by 

# the Free Software Foundation, either version 3 of the License, or 

# (at your option) any later version. 

# 

# This program is distributed in the hope that it will be useful, 

# but WITHOUT ANY WARRANTY; without even the implied warranty of 

# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

# GNU General Public License for more details. 

# 

# You should have received a copy of the LSST License Statement and 

# the GNU General Public License along with this program. If not, 

# see <http://www.lsstcorp.org/LegalNotices/>. 

# 

 

 

__all__ = ["setCallbacks", "mortal"] 

 

import re 

 

from .citizen import Citizen 

 

 

def setCallbacks(new=None, delete=None, both=False): 

"""Set the callback IDs for the Citizen; if both is true, set both new and delete to the same value 

 

You probably want to chant the following to gdb: 

break defaultNewCallback 

break defaultDeleteCallback 

 

You might want to put this in your .gdbinit file. 

 

You can retrieve a citizen's signature from python with obj.repr() 

""" 

 

if both: 

if new: 

if delete and new != delete: 

raise RuntimeError("You may not specify new, delete, and both") 

delete = new 

else: 

new = delete 

 

if new: 

Citizen.setNewCallbackId(new) 

if delete: 

Citizen.setDeleteCallbackId(delete) 

 

 

def mortal(memId0=0, nleakPrintMax=20, first=True, showTypes=None): 

"""!Print leaked memory blocks 

 

@param memId0 Only consider blocks allocated after this memId 

@param nleakPrintMax Maximum number of leaks to print; <= 0 means unlimited 

@param first Print the first nleakPrintMax blocks; if False print the last blocks. 

@param showTypes Only print objects matching this regex (if starts with !, print objects that don't match) 

 

If you want finer control than nleakPrintMax/first provide, use 

Citizen.census() to get the entire list 

 

You can get the next memId to be allocated with mortal("set"), e.g. 

memId0 = mortal("set") 

# work work work 

mortal(memId0) 

""" 

if memId0 == 'set': 

return Citizen.getNextMemId() 

 

nleak = Citizen.census(0, memId0) 

if nleak != 0: 

print("%d Objects leaked" % Citizen.census(0, memId0)) 

 

census = Citizen.census() 

census = [census[i].repr() for i in range(len(census))] # using [i] for some swiggy reason 

if showTypes: 

if showTypes[0] == '!': 

invert = True # invert the matching logic 

showTypes = showTypes[1:] 

else: 

invert = False 

 

_census, census = census, [] 

for c in _census: 

memId, addr, dtype = c.split() 

memId = int(memId[:-1]) 

 

if (not invert and re.search(showTypes, dtype)) or \ 

(invert and not re.search(showTypes, dtype)): 

census.append(c) 

 

nleak = len(census) 

print("%d leaked objects match" % nleak) 

 

if nleakPrintMax <= 0 or nleak <= nleakPrintMax: 

for c in census: 

memId, addr, type = c.split() 

memId = int(memId[:-1]) 

if memId >= memId0: 

print(c) 

else: 

print("...") 

for i in range(nleakPrintMax - 1, -1, -1): 

print(census[i])