forked from SkyLined/mBugId
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cCdbWrapper.py
387 lines (366 loc) · 22.3 KB
/
cCdbWrapper.py
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
import itertools, re, subprocess, threading, time;
from cCdbWrapper_faoGetModulesForFileNameInCurrentProcess import cCdbWrapper_faoGetModulesForFileNameInCurrentProcess;
from cCdbWrapper_fasGetStack import cCdbWrapper_fasGetStack;
from cCdbWrapper_fasReadOutput import cCdbWrapper_fasReadOutput;
from cCdbWrapper_fasSendCommandAndReadOutput import cCdbWrapper_fasSendCommandAndReadOutput;
from cCdbWrapper_fauGetBytes import cCdbWrapper_fauGetBytes;
from cCdbWrapper_fCdbCleanupThread import cCdbWrapper_fCdbCleanupThread;
from cCdbWrapper_fCdbInterruptOnTimeoutThread import cCdbWrapper_fCdbInterruptOnTimeoutThread;
from cCdbWrapper_fCdbStdErrThread import cCdbWrapper_fCdbStdErrThread;
from cCdbWrapper_fCdbStdInOutThread import cCdbWrapper_fCdbStdInOutThread;
from cCdbWrapper_fdoGetModulesByCdbIdForCurrentProcess import cCdbWrapper_fdoGetModulesByCdbIdForCurrentProcess;
from cCdbWrapper_fHandleCreateExitProcess import cCdbWrapper_fHandleCreateExitProcess;
from cCdbWrapper_ftxGetProcessIdAndBinaryNameForCurrentProcess import cCdbWrapper_ftxGetProcessIdAndBinaryNameForCurrentProcess;
from cCdbWrapper_ftxSplitSymbolOrAddress import cCdbWrapper_ftxSplitSymbolOrAddress;
from cCdbWrapper_fsHTMLEncode import cCdbWrapper_fsHTMLEncode;
from cCdbWrapper_fuGetValue import cCdbWrapper_fuGetValue;
from cCdbWrapper_fuGetValueForSymbol import cCdbWrapper_fuGetValueForSymbol;
from cCdbWrapper_f_Timeout import cCdbWrapper_fxSetTimeout, cCdbWrapper_fClearTimeout;
from cCdbWrapper_f_Breakpoint import cCdbWrapper_fuAddBreakpoint, cCdbWrapper_fRemoveBreakpoint;
from cCdbWrapper_fsGetSymbolForAddress import cCdbWrapper_fsGetSymbolForAddress;
from cExcessiveCPUUsageDetector import cExcessiveCPUUsageDetector;
from dxBugIdConfig import dxBugIdConfig;
from sOSISA import sOSISA;
try:
from Kill import fKillProcessesUntilTheyAreDead;
except:
print "*" * 80;
print "BugId depends on Kill, which you can download at https://github.com/SkyLined/Kill/";
print "*" * 80;
raise;
class cCdbWrapper(object):
def __init__(oCdbWrapper,
sCdbISA = None, # Which version of cdb should be used to debug this application?
asApplicationCommandLine = None,
auApplicationProcessIds = None,
asLocalSymbolPaths = None,
asSymbolCachePaths = None,
asSymbolServerURLs = None,
dsURLTemplate_by_srSourceFilePath = None,
rImportantStdOutLines = None,
rImportantStdErrLines = None,
bGenerateReportHTML = False,
fFailedToDebugApplicationCallback = None, # called when the application cannot be started by the debugger, or the
# debugger cannot attach to the given process ids. Arguments:
# (oBugId, sErrorMessage).
fApplicationRunningCallback = None, # called when the application is started in the debugger, or the
# processes the debugger attached to have been resumed.
fApplicationSuspendedCallback = None, # called when the application is suspended to handle an exception,
# timeout or breakpoint.
fApplicationResumedCallback = None, # called after the application was suspended, right before the
# application is resumed again.
fMainProcessTerminatedCallback = None, # called when (any of) the application's "main" processes terminate.
# When BugId starts an application, the first process created is the main
# process. When BugId to attaches to one or more processes, these are the
# main processes. This callback is not called when any child processes
# spawned by these main processes terminate.
fInternalExceptionCallback = None, # called when there is a bug in BugId itself.
fFinishedCallback = None, # called when BugId is finished.
):
oCdbWrapper.sCdbISA = sCdbISA or sOSISA;
oCdbWrapper.asApplicationCommandLine = asApplicationCommandLine;
oCdbWrapper.dsURLTemplate_by_srSourceFilePath = dsURLTemplate_by_srSourceFilePath or {};
oCdbWrapper.rImportantStdOutLines = rImportantStdOutLines;
oCdbWrapper.rImportantStdErrLines = rImportantStdErrLines;
oCdbWrapper.bGenerateReportHTML = bGenerateReportHTML;
oCdbWrapper.fFailedToDebugApplicationCallback = fFailedToDebugApplicationCallback;
oCdbWrapper.fApplicationRunningCallback = fApplicationRunningCallback;
oCdbWrapper.fApplicationSuspendedCallback = fApplicationSuspendedCallback;
oCdbWrapper.fApplicationResumedCallback = fApplicationResumedCallback;
oCdbWrapper.fMainProcessTerminatedCallback = fMainProcessTerminatedCallback;
oCdbWrapper.fInternalExceptionCallback = fInternalExceptionCallback;
oCdbWrapper.fFinishedCallback = fFinishedCallback;
uSymbolOptions = sum([
0x00000001, # SYMOPT_CASE_INSENSITIVE
0x00000002, # SYMOPT_UNDNAME
0x00000004 * (dxBugIdConfig["bDeferredSymbolLoads"] and 1 or 0), # SYMOPT_DEFERRED_LOAD
# 0x00000008, # SYMOPT_NO_CPP
0x00000010 * (dxBugIdConfig["bEnableSourceCodeSupport"] and 1 or 0), # SYMOPT_LOAD_LINES
# 0x00000020, # SYMOPT_OMAP_FIND_NEAREST
# 0x00000040, # SYMOPT_LOAD_ANYTHING
# 0x00000080, # SYMOPT_IGNORE_CVREC
0x00000100 * (not dxBugIdConfig["bDeferredSymbolLoads"] and 1 or 0), # SYMOPT_NO_UNQUALIFIED_LOADS
0x00000200, # SYMOPT_FAIL_CRITICAL_ERRORS
# 0x00000400, # SYMOPT_EXACT_SYMBOLS
0x00000800, # SYMOPT_ALLOW_ABSOLUTE_SYMBOLS
0x00001000 * (not dxBugIdConfig["bUse_NT_SYMBOL_PATH"] and 1 or 0), # SYMOPT_IGNORE_NT_SYMPATH
0x00002000, # SYMOPT_INCLUDE_32BIT_MODULES
# 0x00004000, # SYMOPT_PUBLICS_ONLY
# 0x00008000, # SYMOPT_NO_PUBLICS
0x00010000, # SYMOPT_AUTO_PUBLICS
0x00020000, # SYMOPT_NO_IMAGE_SEARCH
# 0x00040000, # SYMOPT_SECURE
0x00080000, # SYMOPT_NO_PROMPTS
# 0x80000000, # SYMOPT_DEBUG (don't set here: will be switched on and off later as needed)
]);
# Get the cdb binary path
sCdbBinaryPath = dxBugIdConfig["sCdbBinaryPath_%s" % oCdbWrapper.sCdbISA];
assert sCdbBinaryPath, "No %s cdb binary path found" % oCdbWrapper.sCdbISA;
# Get the command line (without starting/attaching to a process)
asCommandLine = [sCdbBinaryPath, "-o", "-sflags", "0x%08X" % uSymbolOptions];
if dxBugIdConfig["bEnableSourceCodeSupport"]:
asCommandLine += ["-lines"];
# Get a list of symbol paths, caches and servers to use:
asLocalSymbolPaths = asLocalSymbolPaths or [];
if asSymbolCachePaths is None:
asSymbolCachePaths = dxBugIdConfig["asDefaultSymbolCachePaths"];
# If not symbols should be used, or no symbol paths are provided, don't use them:
if asSymbolServerURLs is None:
asSymbolServerURLs = dxBugIdConfig["asDefaultSymbolServerURLs"];
oCdbWrapper.bUsingSymbolServers = asSymbolServerURLs;
# Construct the cdb symbol path if one is needed and add it as an argument.
sSymbolsPath = ";".join(asLocalSymbolPaths + ["cache*%s" % x for x in asSymbolCachePaths] + ["srv*%s" % x for x in asSymbolServerURLs]);
if sSymbolsPath:
asCommandLine += ["-y", sSymbolsPath];
oCdbWrapper.auProcessIds = [];
oCdbWrapper.uCurrentProcessId = None; # The current process id in cdb's context
oCdbWrapper.auProcessIdsPendingAttach = auApplicationProcessIds or [];
# Keep track of what the applications "main" processes are.
oCdbWrapper.auMainProcessIds = oCdbWrapper.auProcessIdsPendingAttach[:];
if asApplicationCommandLine is not None:
# If a process must be started, add it to the command line.
assert not auApplicationProcessIds, "Cannot start a process and attach to processes at the same time";
asCommandLine += asApplicationCommandLine;
else:
assert auApplicationProcessIds, "Must start a process or attach to one";
# If any processes must be attached to, add the first to the coommand line.
asCommandLine += ["-p", str(auApplicationProcessIds[0])];
# Quote any non-quoted argument that contain spaces:
asCommandLine = [
(x and (x[0] == '"' or x.find(" ") == -1)) and x or '"%s"' % x.replace('"', '\\"')
for x in asCommandLine
];
# Show the command line if requested.
if dxBugIdConfig["bOutputCommandLine"]:
print "* Starting %s" % " ".join(asCommandLine);
# Initialize some variables
oCdbWrapper.sCurrentISA = None; # During exception handling, this is set to the ISA for the code that caused it.
if bGenerateReportHTML:
oCdbWrapper.asCdbStdIOBlocksHTML = [""]; # Logs stdin/stdout/stderr for the cdb process, grouped by executed command.
oCdbWrapper.oBugReport = None; # Set to a bug report if a bug was detected in the application
oCdbWrapper.uLastProcessId = None; # Set to the id of the last process to be reported as terminated by cdb.
oCdbWrapper.bCdbRunning = True; # Set to False after cdb terminated, used to terminate the debugger thread.
oCdbWrapper.bCdbWasTerminatedOnPurpose = False; # Set to True when cdb is terminated on purpose, used to detect unexpected termination.
if bGenerateReportHTML:
oCdbWrapper.sImportantOutputHTML = ""; # Lines from stdout/stderr that are marked as potentially important to understanding the bug.
# cdb variables are in short supply, so a mechanism must be used to allocate and release them.
# See fuGetVariableId and fReleaseVariableId for implementation details.
oCdbWrapper.uAvailableVariableIds = list(xrange(20)); # $t0-$t19.
# To make it easier to refer to cdb breakpoints by id, a mechanism must be used to allocate and release them
# See fuGetBreakpointId and fReleaseBreakpointId for implementation details.
oCdbWrapper.oBreakpointCounter = itertools.count(); # None have been used so far, so start at 0.
# You can set a breakpoint that results in a bug being reported when it is hit.
# See fuAddBugBreakpoint and fReleaseBreakpointId for implementation details.
oCdbWrapper.duAddress_by_uBreakpointId = {};
oCdbWrapper.duProcessId_by_uBreakpointId = {};
oCdbWrapper.dfCallback_by_uBreakpointId = {};
# You can tell BugId to check for excessive CPU usage among all the threads running in the application.
# See fSetCheckForExcessiveCPUUsageTimeout and cExcessiveCPUUsageDetector.py for more information
oCdbWrapper.oExcessiveCPUUsageDetector = cExcessiveCPUUsageDetector(oCdbWrapper);
# Keep track of future timeouts and their callbacks
oCdbWrapper.axTimeouts = [];
oCdbWrapper.oTimeoutsLock = threading.Lock();
# incremented whenever a CTRL+BREAK event is sent to cdb by the interrupt-on-timeout thread, so the stdio thread
# knows to expect a DBG_CONTROL_BREAK exception and won't report it as an error.
oCdbWrapper.uCdbBreakExceptionsPending = 0;
# oCdbLock is used by oCdbStdInOutThread and oCdbInterruptOnTimeoutThread to allow the former to execute commands
# (other than "g") without the later attempting to get cdb to suspend the application with a breakpoint, and vice
# versa. It's acquired on behalf of the former, to prevent the later from interrupting before the application has
# even started.
oCdbWrapper.oCdbLock = threading.Lock();
oCdbWrapper.oCdbLock.acquire();
oCdbWrapper.bCdbStdInOutThreadRunning = True; # Will be set to false if the thread terminates for any reason.
# Keep track of how long the application has been running, used for timeouts (see fxSetTimeout, fCdbStdInOutThread
# and fCdbInterruptOnTimeoutThread for details. The debugger can tell is what time it thinks it is before we start
# and resume the application as well as what time it thinks it was when an exception happened. The difference is
# used to calculate how long the application has been running. We cannot simply use time.clock() before start/
# resuming and at the time an event is handled as the debugger may take quite some time processing an event before
# we can call time.clock(): this time would incorrectly be added to the time the application has spent running.
# However, while the application is running, we cannot ask the debugger what time it thinks it is, so we have to
# rely on time.clock(). Hence, both values are tracked.
oCdbWrapper.oApplicationTimeLock = threading.Lock();
oCdbWrapper.nApplicationRunTime = 0; # Total time spent running before last interruption
oCdbWrapper.nApplicationResumeDebuggerTime = None; # debugger time at the moment the application was last resumed
oCdbWrapper.nApplicationResumeTime = None; # time.clock() at the moment the application was last resumed
oCdbWrapper.oCdbProcess = subprocess.Popen(
args = " ".join(asCommandLine),
stdin = subprocess.PIPE,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE,
creationflags = subprocess.CREATE_NEW_PROCESS_GROUP,
);
# Create a thread that interacts with the debugger to debug the application
oCdbWrapper.oCdbStdInOutThread = oCdbWrapper._foThread(cCdbWrapper_fCdbStdInOutThread);
# Create a thread that reads stderr output and shows it in the console
oCdbWrapper.oCdbStdErrThread = oCdbWrapper._foThread(cCdbWrapper_fCdbStdErrThread);
# Create a thread that checks for a timeout to interrupt cdb when needed.
oCdbWrapper.oCdbInterruptOnTimeoutThread = oCdbWrapper._foThread(cCdbWrapper_fCdbInterruptOnTimeoutThread);
# Create a thread that waits for the debugger to terminate and cleans up after it.
oCdbWrapper.oCdbCleanupThread = oCdbWrapper._foThread(cCdbWrapper_fCdbCleanupThread);
def fStart(oCdbWrapper):
oCdbWrapper.oCdbStdInOutThread.start();
oCdbWrapper.oCdbStdErrThread.start();
oCdbWrapper.oCdbInterruptOnTimeoutThread.start();
oCdbWrapper.oCdbCleanupThread.start();
def _foThread(oCdbWrapper, fActivity):
return threading.Thread(target = oCdbWrapper._fThreadWrapper, args = (fActivity,));
def _fThreadWrapper(oCdbWrapper, fActivity):
try:
fActivity(oCdbWrapper);
except Exception, oException:
# Start another thread to clean up after the exception was handled.
oThread = threading.Thread(target = oCdbWrapper._fThreadExceptionHandler, args = (oException, threading.currentThread()));
oThread.start();
if oCdbWrapper.fInternalExceptionCallback:
oCdbWrapper.fInternalExceptionCallback(oException);
else:
raise;
def _fThreadExceptionHandler(oCdbWrapper, oException, oExceptionThread):
# Wait for the exception thread to terminate and then clean up.
oExceptionThread.join();
oCdbProcess = getattr(oCdbWrapper, "oCdbProcess", None);
if not oCdbProcess:
oCdbWrapper.bCdbRunning = False;
return;
if oCdbProcess.poll() is not None:
oCdbWrapper.bCdbRunning = False;
return;
oCdbWrapper.bCdbWasTerminatedOnPurpose = True;
# cdb is still running: try to terminate cdb the normal way.
try:
oCdbProcess.terminate();
except:
pass;
else:
oCdbWrapper.bCdbRunning = False;
return;
if oCdbProcess.poll() is not None:
oCdbWrapper.bCdbRunning = False;
return;
# cdb is still running: try to terminate cdb the hard way.
oKillException = None;
try:
fKillProcessesUntilTheyAreDead([oCdbProcess.pid]);
except Exception, oException:
oKillException = oException;
else:
oCdbWrapper.bCdbRunning = False;
# if cdb is *still* running, report and raise an internal exception.
if oCdbProcess.poll() is None:
oKillException = oKillException or AssertionError("cdb did not die after killing it repeatedly")
if oCdbWrapper.fInternalExceptionCallback:
oCdbWrapper.fInternalExceptionCallback(oKillException);
raise oKillException;
# cdb finally died.
oCdbWrapper.bCdbRunning = False;
return;
def fStop(oCdbWrapper):
oCdbWrapper.bCdbWasTerminatedOnPurpose = True;
oCdbProcess = getattr(oCdbWrapper, "oCdbProcess", None);
if oCdbProcess:
try:
oCdbProcess.terminate();
except:
pass;
# The below three threads may have called an event callback, which issued this fStop call. Therefore, we cannot
# wait for them to terminate, as this could mean "waiting until we stop waiting", which takes forever. Since Python
# won't allow you to wait for yourself, this could thow a RuntimeError exception: "cannot join current thread".
# oCdbWrapper.oCdbStdInOutThread.join();
# oCdbWrapper.oCdbStdErrThread.join();
# oCdbWrapper.oCdbCleanupThread.join();
# However, this should not be a problem. The first two thread stop running as soon as they notice cdb has
# terminated. This functions waits for that as well, so the threads should stop at the same time or soon after this
# function returns. This is assuming they have not called a callback that does not return: that is a bug, but not
# in BugIg, but in that callback function. The third thread waits for the first two, does some cleanup and then
# stops running as well. In other words, termination is guaranteed assuming any active callbacks do not block.
oCdbProcess.wait();
oCdbWrapper.bCdbRunning = False;
def __del__(oCdbWrapper):
# Check to make sure the debugger process is not running
oCdbProcess = getattr(oCdbWrapper, "oCdbProcess", None);
if oCdbProcess and oCdbProcess.poll() is None:
print "*** INTERNAL ERROR: cCdbWrapper did not terminate, the cdb process is still running.";
oCdbProcess.terminate();
def fuGetVariableId(oCdbWrapper):
return oCdbWrapper.uAvailableVariableIds.pop();
def fReleaseVariableId(oCdbWrapper, uVariableId):
oCdbWrapper.uAvailableVariableIds.append(uVariableId);
# Select process/thread
def fSelectProcess(oCdbWrapper, uProcessId):
return oCdbWrapper.fSelectProcessAndThread(uProcessId = uProcessId);
def fSelectThread(oCdbWrapper, uThreadId):
return oCdbWrapper.fSelectProcessAndThread(uThreadId = uThreadId);
def fSelectProcessAndThread(oCdbWrapper, uProcessId = None, uThreadId = None):
# Both arguments are optional
sSelectCommand = "";
asSelected = [];
if uProcessId is not None and uProcessId != oCdbWrapper.uCurrentProcessId:
# Only do this if the current process is not the one we need.
sSelectCommand += "|~[0x%X]s;" % uProcessId;
asSelected.append("process");
if uThreadId is not None:
sSelectCommand += "~~[0x%X]s;" % uThreadId;
asSelected.append("thread");
if sSelectCommand:
sSelectCommand += " $$ Select %s" % " and ".join(asSelected);
asSelectOutput = oCdbWrapper.fasSendCommandAndReadOutput(sSelectCommand);
if not oCdbWrapper.bCdbRunning: return;
srIgnoredErrors = r"^\*\*\* (%s)$" % "|".join([
r"WARNING: Unable to verify checksum for .*",
r"ERROR: Module load completed but symbols could not be loaded for .*",
"WARNING: Stack overflow detected\. The unwound frames are extracted from outside normal stack bounds\.",
]);
for sLine in asSelectOutput:
assert re.match(srIgnoredErrors, sLine), \
"Unexpected select process/thread output:\r\n%s" % "\r\n".join(asSelectOutput);
if uProcessId is not None:
oCdbWrapper.uCurrentProcessId = uProcessId;
# Excessive CPU usage
def fSetCheckForExcessiveCPUUsageTimeout(oCdbWrapper, nTimeout):
oCdbWrapper.oExcessiveCPUUsageDetector.fStartTimeout(nTimeout);
def fnApplicationRunTime(oCdbWrapper):
oCdbWrapper.oApplicationTimeLock.acquire();
try:
if oCdbWrapper.nApplicationResumeTime is None:
return oCdbWrapper.nApplicationRunTime;
return oCdbWrapper.nApplicationRunTime + time.clock() - oCdbWrapper.nApplicationResumeTime;
finally:
oCdbWrapper.oApplicationTimeLock.release();
# Get values
def fuGetValue(oCdbWrapper, *axArguments, **dxArguments):
return cCdbWrapper_fuGetValue(oCdbWrapper, *axArguments, **dxArguments);
def fuGetValueForSymbol(oCdbWrapper, *axArguments, **dxArguments):
return cCdbWrapper_fuGetValueForSymbol(oCdbWrapper, *axArguments, **dxArguments);
# Breakpoints
def fuAddBreakpoint(oCdbWrapper, *axArguments, **dxArguments):
return cCdbWrapper_fuAddBreakpoint(oCdbWrapper, *axArguments, **dxArguments);
def fRemoveBreakpoint(oCdbWrapper, *axArguments, **dxArguments):
return cCdbWrapper_fRemoveBreakpoint(oCdbWrapper, *axArguments, **dxArguments);
# Timeouts
def fxSetTimeout(oCdbWrapper, *axArguments, **dxArguments):
return cCdbWrapper_fxSetTimeout(oCdbWrapper, *axArguments, **dxArguments);
def fClearTimeout(oCdbWrapper, *axArguments, **dxArguments):
return cCdbWrapper_fClearTimeout(oCdbWrapper, *axArguments, **dxArguments);
# cdb I/O
def fasReadOutput(oCdbWrapper, *axArguments, **dxArguments):
return cCdbWrapper_fasReadOutput(oCdbWrapper, *axArguments, **dxArguments);
def fasSendCommandAndReadOutput(oCdbWrapper, *axArguments, **dxArguments):
return cCdbWrapper_fasSendCommandAndReadOutput(oCdbWrapper, *axArguments, **dxArguments);
def fHandleCreateExitProcess(oCdbWrapper, *axArguments, **dxArguments):
return cCdbWrapper_fHandleCreateExitProcess(oCdbWrapper, *axArguments, **dxArguments);
def ftxGetProcessIdAndBinaryNameForCurrentProcess(oCdbWrapper, *axArguments, **dxArguments):
return cCdbWrapper_ftxGetProcessIdAndBinaryNameForCurrentProcess(oCdbWrapper, *axArguments, **dxArguments);
def faoGetModulesForFileNameInCurrentProcess(oCdbWrapper, *axArguments, **dxArguments):
return cCdbWrapper_faoGetModulesForFileNameInCurrentProcess(oCdbWrapper, *axArguments, **dxArguments);
def fdoGetModulesByCdbIdForCurrentProcess(oCdbWrapper, *axArguments, **dxArguments):
return cCdbWrapper_fdoGetModulesByCdbIdForCurrentProcess(oCdbWrapper, *axArguments, **dxArguments);
def fasGetStack(oCdbWrapper, *axArguments, **dxArguments):
return cCdbWrapper_fasGetStack(oCdbWrapper, *axArguments, **dxArguments);
def ftxSplitSymbolOrAddress(oCdbWrapper, *axArguments, **dxArguments):
return cCdbWrapper_ftxSplitSymbolOrAddress(oCdbWrapper, *axArguments, **dxArguments);
def fsHTMLEncode(oCdbWrapper, *axArguments, **dxArguments):
return cCdbWrapper_fsHTMLEncode(oCdbWrapper, *axArguments, **dxArguments);
def fsGetSymbolForAddress(oCdbWrapper, *axArguments, **dxArguments):
return cCdbWrapper_fsGetSymbolForAddress(oCdbWrapper, *axArguments, **dxArguments);
def fauGetBytes(oCdbWrapper, *axArguments, **dxArguments):
return cCdbWrapper_fauGetBytes(oCdbWrapper, *axArguments, **dxArguments);