]>
Commit | Line | Data |
---|---|---|
39037602 | 1 | """ |
39236c6e | 2 | A basic caching module for xnu debug macros to use. |
39037602 A |
3 | It is recommended to use [Get|Save][Static|Dynamic]CacheData() apis for |
4 | your caching needs. These APIs will handle the case of clearing caches when | |
5 | a debugger continues and stops or hit a breakpoint. | |
39236c6e A |
6 | |
7 | Use Static caches for data that will not change if the program is run and stopped again. e.g. typedata, version numbers etc. | |
8 | An example invocation could be like | |
9 | def getDSYMPathForUUID(uuid): | |
10 | # Get the data from cache | |
11 | cached_data = caching.GetStaticCacheData('dsym.for.uuid', {}) | |
39037602 | 12 | |
39236c6e A |
13 | if uuid in cached_data: |
14 | return cached_data[uuid] | |
15 | else: | |
16 | path = #get info for uuid | |
17 | cached_data[uuid] = path | |
18 | ||
19 | # save the cached_data object to cache. | |
20 | caching.SaveStaticCacheData('dsym.for.uuid', cached_data) | |
39037602 | 21 | |
39236c6e A |
22 | return cached_data[uuid] |
23 | ||
39037602 A |
24 | And use Dynamic caches for things like thread data, zones information etc. |
25 | These will automatically be dropped when debugger continues the target | |
39236c6e A |
26 | An example use of Dynamic cache could be as follows |
27 | ||
28 | def GetExecutablePathForPid(pid): | |
29 | # Get the data from cache | |
30 | cached_data = caching.GetDynamicCacheData('exec_for_path', {}) | |
39037602 | 31 | |
39236c6e A |
32 | if pid in cached_data: |
33 | return cached_data[pid] | |
34 | else: | |
35 | exec_path = "/path/to/exec" #get exec path for pid | |
36 | cached_data[pid] = path | |
37 | ||
38 | # save the cached_data object to cache. | |
39 | caching.SaveDynamicCacheData('exec_for_path', cached_data) | |
39037602 | 40 | |
39236c6e A |
41 | return cached_data[pid] |
42 | ||
43 | """ | |
44 | ||
45 | #Private Routines and objects | |
46 | ||
47 | from configuration import * | |
48 | ||
49 | import sys | |
50 | ||
51 | """ | |
39037602 | 52 | The format for the saved data dictionaries is |
39236c6e A |
53 | { |
54 | 'key' : (valueobj, versno), | |
55 | ... | |
56 | } | |
57 | ||
58 | The versno is an int defining the version of obj. In case of version mismatch it will set valueobj to default upon access. | |
59 | ||
60 | """ | |
61 | _static_data = {} | |
62 | _dynamic_data = {} | |
63 | ||
64 | ||
65 | ||
66 | def _GetDebuggerSessionID(): | |
39037602 | 67 | """ A default callable function that _GetCurrentSessionID uses to |
39236c6e A |
68 | identify a stopped session. |
69 | """ | |
70 | return 0 | |
71 | ||
72 | def _GetCurrentSessionID(): | |
73 | """ Get the current session id. This will update whenever | |
74 | system is continued or if there is new information that would | |
75 | cause the dynamic cache to be deleted. | |
76 | ||
77 | returns: int - session id number. | |
78 | """ | |
79 | session_id = _GetDebuggerSessionID() | |
80 | return session_id; | |
81 | ||
82 | ||
39037602 A |
83 | #Public APIs |
84 | ||
85 | def ClearAllCache(): | |
86 | """ remove all cached data. | |
87 | """ | |
88 | global _static_data, _dynamic_data | |
89 | _static_data = {} | |
90 | _dynamic_data = {} | |
39236c6e A |
91 | |
92 | def GetSizeOfCache(): | |
93 | """ Returns number of bytes held in cache. | |
94 | returns: | |
95 | int - size of cache including static and dynamic | |
96 | """ | |
97 | global _static_data, _dynamic_data | |
98 | return sys.getsizeof(_static_data) + sys.getsizeof(_dynamic_data) | |
99 | ||
100 | ||
101 | def GetStaticCacheData(key, default_value = None): | |
39037602 | 102 | """ Get cached object based on key from the cache of static information. |
39236c6e A |
103 | params: |
104 | key: str - a unique string identifying your data. | |
105 | default_value : obj - an object that should be returned if key is not found. | |
106 | returns: | |
107 | default_value - if the static cache does not have your data. | |
108 | obj - The data obj saved with SaveStaticCacheData() | |
109 | """ | |
110 | global _static_data | |
111 | key = str(key) | |
112 | if key in _static_data: | |
113 | return _static_data[key][0] | |
114 | return default_value | |
115 | ||
116 | def SaveStaticCacheData(key, value): | |
117 | """ Save data into the cache identified by key. | |
118 | It will overwrite any data that was previously associated with key | |
119 | params: | |
120 | key : str - a unique string identifying your data | |
121 | value: obj - any object that is to be cached. | |
122 | returns: | |
123 | Nothing | |
124 | """ | |
125 | global _static_data | |
126 | ||
127 | if not config['CacheStaticData']: | |
128 | return | |
39037602 | 129 | |
39236c6e A |
130 | key = str(key) |
131 | _static_data[key] = (value, _GetCurrentSessionID()) | |
132 | return | |
133 | ||
134 | ||
135 | def GetDynamicCacheData(key, default_value=None): | |
136 | """ Get cached object based on key from the cache of dynamic information. | |
137 | params: | |
138 | key: str - a unique string identifying cached object | |
139 | default_value : obj - an object that should be returned if key is not found. | |
140 | returns: | |
141 | default_value - if dynamic cache does not have data or if the saved version mismatches with current session id. | |
142 | obj - The data obj saved with SaveDynamicCacheData() | |
143 | """ | |
144 | global _dynamic_data | |
145 | key = str(key) | |
146 | if key in _dynamic_data: | |
147 | if _GetCurrentSessionID() == _dynamic_data[key][1]: | |
148 | return _dynamic_data[key][0] | |
149 | else: | |
150 | del _dynamic_data[key] | |
151 | ||
152 | return default_value | |
153 | ||
154 | ||
155 | def SaveDynamicCacheData(key, value): | |
156 | """ Save data into the cache identified by key. | |
157 | It will overwrite any data that was previously associated with key | |
158 | params: | |
159 | key : str - a unique string identifying your data | |
160 | value: obj - any object that is to be cached. | |
161 | returns: | |
162 | Nothing | |
163 | """ | |
164 | global _dynamic_data | |
165 | ||
166 | if not config['CacheDynamicData']: | |
167 | return | |
168 | ||
169 | key = str(key) | |
170 | _dynamic_data[key] = (value, _GetCurrentSessionID()) | |
171 | ||
172 | return |