processmon.cpp 25.9 KB
Newer Older
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
1 2
#include "stdafx.h"

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
3 4 5 6 7
#include <map>

#include <boost/thread/recursive_mutex.hpp>
#include <boost/atomic.hpp>

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
8 9 10 11 12 13 14
#include "processmon.h"

namespace kdlib
{

///////////////////////////////////////////////////////////////////////////////

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
15 16 17 18 19 20 21 22 23 24 25 26 27
class ProcessInfo;
typedef boost::shared_ptr<ProcessInfo>  ProcessInfoPtr;

///////////////////////////////////////////////////////////////////////////////

class ProcessInfo {

public:

    ModulePtr getModule(MEMOFFSET_64  offset);
    void insertModule( ModulePtr& module);
    void removeModule(MEMOFFSET_64  offset );

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
28 29 30
    TypeInfoPtr getTypeInfo(const std::wstring& name);
    void insertTypeInfo(const TypeInfoPtr& typeInfo);

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
31 32
    void insertBreakpoint(BreakpointPtr& breakpoint);
    void removeBreakpoint(BreakpointPtr& breakpoint);
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
33

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
34
    DebugCallbackResult breakpointHit(BreakpointPtr& breakpoint);
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
35

36 37
    void onChangeSymbolPaths();

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
38 39 40 41 42
private:

    typedef std::map<MEMOFFSET_64, ModulePtr> ModuleMap;
    ModuleMap  m_moduleMap;
    boost::recursive_mutex  m_moduleLock;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
43 44 45 46

    typedef std::map<std::wstring, TypeInfoPtr>  TypeInfoMap;
    TypeInfoMap  m_typeInfoMap;
    boost::recursive_mutex  m_typeInfoLock;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
47
    
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
48 49 50
    typedef std::map<BREAKPOINT_ID, BreakpointPtr>  BreakpointIdMap;
    BreakpointIdMap  m_breakpointMap;
    boost::recursive_mutex  m_breakpointLock;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
51 52 53 54 55 56 57 58 59 60 61
};

///////////////////////////////////////////////////////////////////////////////

class ProcessMonitorImpl {

public:

    ProcessMonitorImpl() : m_bpUnique(0x80000000)
    {}

62 63 64
    ~ProcessMonitorImpl()
    {}

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
65 66
public:

SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
67 68
    DebugCallbackResult processStart(PROCESS_DEBUG_ID id);
    DebugCallbackResult processStop(PROCESS_DEBUG_ID id, ProcessExitReason reason, unsigned int ExitCode);
69 70
    void processAllDetach();
    void processAllTerminate();
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
71
    unsigned int getNumberProcesses();
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
72

SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
73 74 75
    DebugCallbackResult createThread();
    DebugCallbackResult stopThread();

SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
76 77
    DebugCallbackResult moduleLoad(PROCESS_DEBUG_ID id, MEMOFFSET_64 offset, const std::wstring& moduleName);
    DebugCallbackResult moduleUnload(PROCESS_DEBUG_ID id, MEMOFFSET_64  offset, const std::wstring& moduleName);
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
78
    DebugCallbackResult breakpointHit(PROCESS_DEBUG_ID id, BreakpointPtr& breakpoint);
SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
79 80
    void currentThreadChange(THREAD_DEBUG_ID threadid);
    void executionStatusChange(ExecutionStatus status);
81
    void localScopeChange();
82
    void changeSymbolPaths();
83
    void breakpointsChange(PROCESS_DEBUG_ID id);
SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
84
    DebugCallbackResult  exceptionHit(const ExceptionInfo& excinfo);
ussrhero's avatar
ussrhero committed
85
    void debugOutput(const std::wstring& text, OutputFlag flag);
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
86 87
    void startInput();
    void stopInput();
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
88 89 90 91

    ModulePtr getModule( MEMOFFSET_64  offset, PROCESS_DEBUG_ID id );
    void insertModule( ModulePtr& module, PROCESS_DEBUG_ID id );

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
92 93 94
    TypeInfoPtr getTypeInfo(const std::wstring& name, PROCESS_DEBUG_ID id = -1);
    void insertTypeInfo(const TypeInfoPtr& typeInfo, PROCESS_DEBUG_ID id = -1);

SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
95 96 97
    void registerEventsCallback(DebugEventsCallback *callback);
    void removeEventsCallback(DebugEventsCallback *callback);

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
98 99 100
    void registerBreakpoint( BreakpointPtr& breakpoint, PROCESS_DEBUG_ID id = -1 );
    void removeBreakpoint( BreakpointPtr& breakpoint, PROCESS_DEBUG_ID id = -1 );

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
101 102 103 104 105 106 107 108 109 110 111
private:

    ProcessInfoPtr  getProcess( PROCESS_DEBUG_ID id );

    boost::recursive_mutex  m_lock;

    typedef std::map<PROCESS_DEBUG_ID, ProcessInfoPtr>  ProcessMap;
    ProcessMap  m_processMap;

    boost::atomic<unsigned long long>  m_bpUnique;

SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
112 113 114 115 116 117
private:

    typedef std::list<DebugEventsCallback*>  EventsCallbackList;

    boost::recursive_mutex      m_callbacksLock;
    EventsCallbackList          m_callbacks;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
118 119
};

120
ProcessMonitorImpl*  g_procmon;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139

///////////////////////////////////////////////////////////////////////////////

class CurrentProcessGuard {

public:

    CurrentProcessGuard() :
        m_procId( getCurrentProcessId() )
        {}

    ~CurrentProcessGuard() {
        setCurrentProcessById(m_procId);
    }

private:

    PROCESS_DEBUG_ID  m_procId;
};
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
140 141 142 143 144

///////////////////////////////////////////////////////////////////////////////

void ProcessMonitor::init()
{
145 146
    if (!g_procmon)
        g_procmon = new ProcessMonitorImpl();
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
147 148 149 150 151 152
}

///////////////////////////////////////////////////////////////////////////////

void ProcessMonitor::deinit()
{
153 154 155 156 157
    if (g_procmon)
    {
        delete  g_procmon;
        g_procmon = nullptr;
    }
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
158 159
}

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
160
/////////////////////////////////////////////////////////////////////////////
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
161

SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
162
void ProcessMonitor::registerEventsCallback(DebugEventsCallback *callback)
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
163
{
SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
164
    g_procmon->registerEventsCallback(callback);
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
165
}
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
166

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
167
/////////////////////////////////////////////////////////////////////////////
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
168

SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
169
void ProcessMonitor::removeEventsCallback(DebugEventsCallback *callback)
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
170
{
SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
171 172 173 174 175
    g_procmon->removeEventsCallback(callback);
}

/////////////////////////////////////////////////////////////////////////////

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
void ProcessMonitor::registerBreakpoint( BreakpointPtr& breakpoint, PROCESS_DEBUG_ID id )
{
    if ( id == -1 )
        id = getCurrentProcessId();

    g_procmon->registerBreakpoint(breakpoint, id);
}


/////////////////////////////////////////////////////////////////////////////

void ProcessMonitor::removeBreakpoint( BreakpointPtr& breakpoint, PROCESS_DEBUG_ID id )
{
    if ( id == -1 )
        id = getCurrentProcessId();

    g_procmon->removeBreakpoint(breakpoint, id);
}

/////////////////////////////////////////////////////////////////////////////

SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
197 198 199 200 201 202 203 204 205 206
DebugCallbackResult ProcessMonitor::processStart(PROCESS_DEBUG_ID id)
{
    return g_procmon->processStart(id);
}

/////////////////////////////////////////////////////////////////////////////

DebugCallbackResult ProcessMonitor::processStop(PROCESS_DEBUG_ID id, ProcessExitReason reason, unsigned int exitCode)
{
    return g_procmon->processStop(id, reason, exitCode);
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
207 208 209 210
}

///////////////////////////////////////////////////////////////////////////////

SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
211 212 213 214 215 216 217 218 219 220 221 222 223 224
DebugCallbackResult ProcessMonitor::createThread()
{
    return g_procmon->createThread();
}

///////////////////////////////////////////////////////////////////////////////

DebugCallbackResult ProcessMonitor::stopThread()
{
    return g_procmon->stopThread();
}

///////////////////////////////////////////////////////////////////////////////

225
void ProcessMonitor::processAllTerminate()
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
226
{
227
    g_procmon->processAllTerminate();
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
228
}
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
229

230 231 232 233 234 235 236
///////////////////////////////////////////////////////////////////////////////

void ProcessMonitor::processAllDetach()
{
    g_procmon->processAllDetach();
}

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
237 238
///////////////////////////////////////////////////////////////////////////////

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
239 240 241 242 243 244 245
unsigned int ProcessMonitor::getNumberProcesses()
{
    return g_procmon->getNumberProcesses();
}

///////////////////////////////////////////////////////////////////////////////

SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
246
DebugCallbackResult ProcessMonitor::moduleLoad(PROCESS_DEBUG_ID id, MEMOFFSET_64 offset, const std::wstring& moduleName)
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
247
{
SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
248
    return g_procmon->moduleLoad(id, offset, moduleName);
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
249 250 251 252
}

///////////////////////////////////////////////////////////////////////////////

SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
253
DebugCallbackResult ProcessMonitor::moduleUnload(PROCESS_DEBUG_ID id, MEMOFFSET_64  offset, const std::wstring& moduleName)
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
254
{
SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
255
    return g_procmon->moduleUnload(id, offset, moduleName);
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
256 257 258 259
}

///////////////////////////////////////////////////////////////////////////////

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
260
DebugCallbackResult ProcessMonitor::breakpointHit(PROCESS_DEBUG_ID id, BreakpointPtr& breakpoint)
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
261
{
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
262
    return g_procmon->breakpointHit(id, breakpoint);
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
263 264 265 266
}

///////////////////////////////////////////////////////////////////////////////

SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
267 268 269 270 271 272 273 274 275 276 277 278 279 280
void ProcessMonitor::currentThreadChange(THREAD_DEBUG_ID id)
{
    g_procmon->currentThreadChange(id);
}

///////////////////////////////////////////////////////////////////////////////

void ProcessMonitor::executionStatusChange(ExecutionStatus status)
{
    g_procmon->executionStatusChange(status);
}

///////////////////////////////////////////////////////////////////////////////

281 282 283 284 285 286 287
void ProcessMonitor::localScopeChange()
{
    g_procmon->localScopeChange();
}

///////////////////////////////////////////////////////////////////////////////

288 289 290 291 292 293 294
void ProcessMonitor::changeSymbolPaths()
{
    g_procmon->changeSymbolPaths();
}

///////////////////////////////////////////////////////////////////////////////

295
void ProcessMonitor::breakpointsChange(PROCESS_DEBUG_ID id)
296
{
297
    g_procmon->breakpointsChange(id);
298 299 300 301
}

///////////////////////////////////////////////////////////////////////////////

SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
302 303 304 305 306 307 308
DebugCallbackResult ProcessMonitor::exceptionHit(const ExceptionInfo& excinfo)
{
    return g_procmon->exceptionHit(excinfo);
}

///////////////////////////////////////////////////////////////////////////////

ussrhero's avatar
ussrhero committed
309
void ProcessMonitor::debugOutput(const std::wstring& text, OutputFlag flag)
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
310
{
ussrhero's avatar
ussrhero committed
311
    g_procmon->debugOutput(text, flag);
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
312 313 314 315 316 317 318 319 320 321 322 323 324 325
}

///////////////////////////////////////////////////////////////////////////////

void ProcessMonitor::startInput()
{
    g_procmon->startInput();
}

///////////////////////////////////////////////////////////////////////////////

void ProcessMonitor::stopInput()
{
    g_procmon->stopInput();
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
326 327 328 329
}

///////////////////////////////////////////////////////////////////////////////

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
ModulePtr ProcessMonitor::getModule( MEMOFFSET_64  offset, PROCESS_DEBUG_ID id )
{
    if ( id == -1 )
        id = getCurrentProcessId();

    return g_procmon->getModule(offset,id);
}

///////////////////////////////////////////////////////////////////////////////

void ProcessMonitor::insertModule( ModulePtr& module, PROCESS_DEBUG_ID id )
{
    if ( id == -1 )
        id = getCurrentProcessId();

    return g_procmon->insertModule(module, id);
}

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366
///////////////////////////////////////////////////////////////////////////////

TypeInfoPtr ProcessMonitor::getTypeInfo(const std::wstring& name, PROCESS_DEBUG_ID id)
{
    if (id == -1)
        id = getCurrentProcessId();

    return g_procmon->getTypeInfo(name, id);
}

///////////////////////////////////////////////////////////////////////////////

void ProcessMonitor::insertTypeInfo(const TypeInfoPtr& typeInfo, PROCESS_DEBUG_ID id)
{
    if (id == -1)
        id = getCurrentProcessId();

    return g_procmon->insertTypeInfo(typeInfo, id);
}
367 368 369

///////////////////////////////////////////////////////////////////////////////

SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
370
DebugCallbackResult ProcessMonitorImpl::processStart(PROCESS_DEBUG_ID id)
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
371
{
SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
372 373 374 375 376 377 378 379
    {
        ProcessInfoPtr  proc = ProcessInfoPtr(new ProcessInfo());
        boost::recursive_mutex::scoped_lock l(m_lock);
        m_processMap[id] = proc;
    }

    DebugCallbackResult  result = DebugCallbackNoChange;

SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
380 381 382 383 384 385 386 387 388 389
    boost::recursive_mutex::scoped_lock l(m_callbacksLock);

    EventsCallbackList::iterator  it = m_callbacks.begin();

    for (; it != m_callbacks.end(); ++it)
    {
        DebugCallbackResult  ret = (*it)->onProcessStart(id);
        result = ret != DebugCallbackNoChange ? ret : result;
    }

SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
390
    return result;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
391 392
}

SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
393

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
394 395
///////////////////////////////////////////////////////////////////////////////

SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
396
DebugCallbackResult ProcessMonitorImpl::processStop(PROCESS_DEBUG_ID id, ProcessExitReason reason, unsigned int exitCode)
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
397
{
SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
398 399 400 401 402 403 404 405 406 407 408 409 410 411 412
    {
        boost::recursive_mutex::scoped_lock l(m_lock);
        m_processMap.erase(id);
    }

    DebugCallbackResult  result = DebugCallbackNoChange;

    boost::recursive_mutex::scoped_lock l(m_callbacksLock);

    EventsCallbackList::iterator  it = m_callbacks.begin();

    for (; it != m_callbacks.end(); ++it)
    {
        DebugCallbackResult  ret = (*it)->onProcessExit(id, reason, exitCode);
        result = ret != DebugCallbackNoChange ? ret : result;
SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450
    }

    return result;
}

///////////////////////////////////////////////////////////////////////////////

DebugCallbackResult ProcessMonitorImpl::createThread()
{
    DebugCallbackResult  result = DebugCallbackNoChange;

    boost::recursive_mutex::scoped_lock l(m_callbacksLock);

    EventsCallbackList::iterator  it = m_callbacks.begin();

    for (; it != m_callbacks.end(); ++it)
    {
        DebugCallbackResult  ret = (*it)->onThreadStart();
        result = ret != DebugCallbackNoChange ? ret : result;
    }

    return result;
}

///////////////////////////////////////////////////////////////////////////////

DebugCallbackResult ProcessMonitorImpl::stopThread()
{
    DebugCallbackResult  result = DebugCallbackNoChange;

    boost::recursive_mutex::scoped_lock l(m_callbacksLock);

    EventsCallbackList::iterator  it = m_callbacks.begin();

    for (; it != m_callbacks.end(); ++it)
    {
        DebugCallbackResult  ret = (*it)->onThreadStop();
        result = ret != DebugCallbackNoChange ? ret : result;
SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
451 452 453
    }

    return result;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
454 455 456
}

///////////////////////////////////////////////////////////////////////////////
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
457

458
void ProcessMonitorImpl::processAllTerminate()
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
459
{
460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475
    while (!m_processMap.empty())
    {
        PROCESS_DEBUG_ID id = m_processMap.begin()->first;
        processStop(id, ProcessTerminate, 0);
    }
}

///////////////////////////////////////////////////////////////////////////////

void ProcessMonitorImpl::processAllDetach()
{
    while (!m_processMap.empty())
    {
        PROCESS_DEBUG_ID id = m_processMap.begin()->first;
        processStop(id, ProcessDetach, 0);
    }
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
476 477 478 479
}

///////////////////////////////////////////////////////////////////////////////

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
480 481 482
unsigned int ProcessMonitorImpl::getNumberProcesses()
{
    boost::recursive_mutex::scoped_lock l(m_lock);
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
483
    return static_cast<unsigned int>(m_processMap.size());
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
484 485 486 487
}

///////////////////////////////////////////////////////////////////////////////

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
488
ModulePtr ProcessMonitorImpl::getModule( MEMOFFSET_64  offset, PROCESS_DEBUG_ID id )
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
489
{
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
490 491 492
    ProcessInfoPtr  processInfo = getProcess(id);

    ModulePtr  module;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
493 494

    if ( processInfo )
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
495 496 497
        module = processInfo->getModule(offset);

    return module;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
498 499 500 501
}

///////////////////////////////////////////////////////////////////////////////

SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
502
DebugCallbackResult ProcessMonitorImpl::moduleLoad(PROCESS_DEBUG_ID id, MEMOFFSET_64 offset, const std::wstring& moduleName)
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
503
{
SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
504 505
    DebugCallbackResult  result = DebugCallbackNoChange;

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
506 507
    ProcessInfoPtr  processInfo = getProcess(id);

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
508 509
    if ( processInfo )
    {
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
510 511
        processInfo->removeModule( offset );
        loadModule(offset);
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
512
    }
SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
513 514 515 516 517 518 519 520 521 522 523

    boost::recursive_mutex::scoped_lock l(m_callbacksLock);

    EventsCallbackList::iterator  it;
    for (it = m_callbacks.begin(); it != m_callbacks.end(); ++it)
    {
        DebugCallbackResult  ret = (*it)->onModuleLoad(offset, moduleName);
        result = ret != DebugCallbackNoChange ? ret : result;
    }

    return result;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
524 525 526 527
}

///////////////////////////////////////////////////////////////////////////////

SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
528
DebugCallbackResult ProcessMonitorImpl::moduleUnload(PROCESS_DEBUG_ID id, MEMOFFSET_64  offset, const std::wstring &moduleName)
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
529
{
SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
530 531
    DebugCallbackResult  result = DebugCallbackNoChange;

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
532
    ProcessInfoPtr  processInfo = getProcess(id);
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
533

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
534 535
    if ( processInfo )
        processInfo->removeModule( offset );
SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
536 537 538 539 540 541 542 543 544 545 546

    boost::recursive_mutex::scoped_lock l(m_callbacksLock);

    EventsCallbackList::iterator  it;
    for ( it = m_callbacks.begin(); it != m_callbacks.end(); ++it )
    {
        DebugCallbackResult  ret = (*it)->onModuleUnload(offset, moduleName );
        result = ret != DebugCallbackNoChange ? ret : result;
    }

    return result;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
547
}
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
548

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
549 550
///////////////////////////////////////////////////////////////////////////////

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
551
DebugCallbackResult ProcessMonitorImpl::breakpointHit(PROCESS_DEBUG_ID id, BreakpointPtr& breakpoint)
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
552
{
SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
553 554
    DebugCallbackResult  result = DebugCallbackNoChange;

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
555 556
    ProcessInfoPtr  processInfo = getProcess(id);
    if ( processInfo )
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
557
        result = processInfo->breakpointHit(breakpoint);
SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
558 559 560 561 562 563

    boost::recursive_mutex::scoped_lock l(m_callbacksLock);

    EventsCallbackList::iterator  it;
    for (it = m_callbacks.begin(); it != m_callbacks.end(); ++it)
    {
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
564
        DebugCallbackResult  ret = (*it)->onBreakpoint(breakpoint->getId());
SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
565 566
        result = ret != DebugCallbackNoChange ? ret : result;
    }
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
567

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
568
    return result;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
569 570
}

SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597
///////////////////////////////////////////////////////////////////////////////

void ProcessMonitorImpl::currentThreadChange(THREAD_DEBUG_ID threadid)
{
    boost::recursive_mutex::scoped_lock l(m_callbacksLock);

    EventsCallbackList::iterator  it = m_callbacks.begin();

    for (; it != m_callbacks.end(); ++it)
    {
        (*it)->onCurrentThreadChange(threadid);
    }
}

///////////////////////////////////////////////////////////////////////////////

void ProcessMonitorImpl::executionStatusChange(ExecutionStatus status)
{
    boost::recursive_mutex::scoped_lock l(m_callbacksLock);

    EventsCallbackList::iterator  it = m_callbacks.begin();

    for (; it != m_callbacks.end(); ++it)
    {
        (*it)->onExecutionStatusChange(status);
    }
}
598 599 600

///////////////////////////////////////////////////////////////////////////////

601
void ProcessMonitorImpl::localScopeChange()
602 603 604 605 606 607 608 609 610 611 612
{
    boost::recursive_mutex::scoped_lock l(m_callbacksLock);

    EventsCallbackList::iterator  it = m_callbacks.begin();

    for (; it != m_callbacks.end(); ++it)
    {
        (*it)->onChangeLocalScope();
    }
}

SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
613 614
///////////////////////////////////////////////////////////////////////////////

615 616 617
void ProcessMonitorImpl::changeSymbolPaths()
{

618 619 620 621 622 623
    {
        boost::recursive_mutex::scoped_lock l(m_lock);

        for ( ProcessMap::iterator  it = m_processMap.begin(); it != m_processMap.end(); ++it)
           it->second->onChangeSymbolPaths();
    }
624 625

    {
626 627 628 629 630 631 632 633
        boost::recursive_mutex::scoped_lock l(m_callbacksLock);

        EventsCallbackList::iterator  it = m_callbacks.begin();

        for (; it != m_callbacks.end(); ++it)
        {
            (*it)->onChangeSymbolPaths();
        }
634 635 636 637 638
    }
}

///////////////////////////////////////////////////////////////////////////////

639 640 641 642 643 644 645 646 647 648 649 650 651 652
void ProcessMonitorImpl::breakpointsChange(PROCESS_DEBUG_ID id)
{
    boost::recursive_mutex::scoped_lock l(m_callbacksLock);

    EventsCallbackList::iterator  it = m_callbacks.begin();

    for (; it != m_callbacks.end(); ++it)
    {
        (*it)->onChangeBreakpoints();
    }
}

///////////////////////////////////////////////////////////////////////////////

SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
653 654 655 656 657 658 659 660 661 662 663 664 665 666 667
DebugCallbackResult  ProcessMonitorImpl::exceptionHit(const ExceptionInfo& excinfo)
{
    DebugCallbackResult  result = DebugCallbackNoChange;

    boost::recursive_mutex::scoped_lock l(m_callbacksLock);

    EventsCallbackList::iterator  it;
    for (it = m_callbacks.begin(); it != m_callbacks.end(); ++it)
    {
        DebugCallbackResult  ret = (*it)->onException(excinfo);
        result = ret != DebugCallbackNoChange ? ret : result;
    }

    return result;
}
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
668

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
669 670
///////////////////////////////////////////////////////////////////////////////

ussrhero's avatar
ussrhero committed
671
void ProcessMonitorImpl::debugOutput(const std::wstring& text, OutputFlag flag)
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
672 673 674 675 676 677
{
    boost::recursive_mutex::scoped_lock l(m_callbacksLock);

    EventsCallbackList::iterator  it;
    for (it = m_callbacks.begin(); it != m_callbacks.end(); ++it)
    {
ussrhero's avatar
ussrhero committed
678
        (*it)->onDebugOutput(text, flag);
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
679 680 681 682 683
    }
}

///////////////////////////////////////////////////////////////////////////////

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709
void ProcessMonitorImpl::startInput()
{
    boost::recursive_mutex::scoped_lock l(m_callbacksLock);

    EventsCallbackList::iterator  it;
    for (it = m_callbacks.begin(); it != m_callbacks.end(); ++it)
    {
        (*it)->onStartInput();
    }
}

///////////////////////////////////////////////////////////////////////////////

void ProcessMonitorImpl::stopInput()
{
    boost::recursive_mutex::scoped_lock l(m_callbacksLock);

    EventsCallbackList::iterator  it;
    for (it = m_callbacks.begin(); it != m_callbacks.end(); ++it)
    {
        (*it)->onStopInput();
    }
}

///////////////////////////////////////////////////////////////////////////////

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
710 711 712 713 714 715 716 717 718
void ProcessMonitorImpl::insertModule( ModulePtr& module, PROCESS_DEBUG_ID id )
{
    ProcessInfoPtr  processInfo = getProcess(id);
    if ( processInfo )
        return processInfo->insertModule(module);
}

///////////////////////////////////////////////////////////////////////////////

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738
TypeInfoPtr ProcessMonitorImpl::getTypeInfo(const std::wstring& name, PROCESS_DEBUG_ID id)
{
    ProcessInfoPtr  processInfo = getProcess(id);
    if ( processInfo )
        return processInfo->getTypeInfo(name);

    return TypeInfoPtr();
}

///////////////////////////////////////////////////////////////////////////////

void ProcessMonitorImpl::insertTypeInfo(const TypeInfoPtr& typeInfo, PROCESS_DEBUG_ID id)
{
    ProcessInfoPtr  processInfo = getProcess(id);
    if (processInfo)
        return processInfo->insertTypeInfo(typeInfo);
}

///////////////////////////////////////////////////////////////////////////////

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
739
ProcessInfoPtr ProcessMonitorImpl::getProcess( PROCESS_DEBUG_ID id )
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
740
{
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
741
    boost::recursive_mutex::scoped_lock l(m_lock);
742 743 744 745 746 747 748 749 750 751

    ProcessMap::iterator  it  = m_processMap.find(id);

    if ( it != m_processMap.end() )
        return it->second;

    ProcessInfoPtr  proc = ProcessInfoPtr( new ProcessInfo() );
    m_processMap[id] = proc;

    return proc;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
752 753
}

SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770

///////////////////////////////////////////////////////////////////////////////

void ProcessMonitorImpl::registerEventsCallback(DebugEventsCallback *callback)
{
    boost::recursive_mutex::scoped_lock l(m_callbacksLock);
    m_callbacks.push_back(callback);
}

///////////////////////////////////////////////////////////////////////////////

void ProcessMonitorImpl::removeEventsCallback(DebugEventsCallback *callback)
{
    boost::recursive_mutex::scoped_lock l(m_callbacksLock);
    m_callbacks.remove(callback);
}

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
771 772
///////////////////////////////////////////////////////////////////////////////

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796
void ProcessMonitorImpl::registerBreakpoint( BreakpointPtr& breakpoint, PROCESS_DEBUG_ID id )
{
    ProcessInfoPtr  processInfo = getProcess(id);

    if ( processInfo )
    {
        processInfo->insertBreakpoint(breakpoint);
    }
}

///////////////////////////////////////////////////////////////////////////////

void ProcessMonitorImpl::removeBreakpoint( BreakpointPtr& breakpoint, PROCESS_DEBUG_ID id )
{
    ProcessInfoPtr  processInfo = getProcess(id);

    if ( processInfo )
    {
        processInfo->removeBreakpoint(breakpoint);
    }
}

///////////////////////////////////////////////////////////////////////////////

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
797
ModulePtr ProcessInfo::getModule(MEMOFFSET_64  offset)
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
798
{
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
799
    boost::recursive_mutex::scoped_lock l(m_moduleLock);
800 801 802 803 804 805 806 807 808 809 810 811 812 813 814

    ModuleMap::iterator it = m_moduleMap.find(offset);

    if ( it != m_moduleMap.end() )
        return it->second;

    for ( ModuleMap::iterator it = m_moduleMap.begin(); it != m_moduleMap.end(); ++it )
    {
        if ( it->second->getBase() <= offset && offset < it->second->getEnd() )
        {
           return it->second;
        }
    }

    return ModulePtr();
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
815 816 817 818
}

///////////////////////////////////////////////////////////////////////////////

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
819
void ProcessInfo::insertModule( ModulePtr& module)
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
820
{
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
821 822
    boost::recursive_mutex::scoped_lock l(m_moduleLock);
    m_moduleMap[ module->getBase() ] = module;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
823 824 825 826
}

///////////////////////////////////////////////////////////////////////////////

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
827
void ProcessInfo::removeModule(MEMOFFSET_64  offset )
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
828
{
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
829
    boost::recursive_mutex::scoped_lock l(m_moduleLock);
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
830 831 832 833 834
    m_moduleMap.erase(offset);
}

///////////////////////////////////////////////////////////////////////////////

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857
TypeInfoPtr ProcessInfo::getTypeInfo(const std::wstring& name)
{
    boost::recursive_mutex::scoped_lock l(m_typeInfoLock);

    TypeInfoMap::iterator  it = m_typeInfoMap.find(name);

    if (it != m_typeInfoMap.end())
        return it->second;

    return TypeInfoPtr();
}

///////////////////////////////////////////////////////////////////////////////

void ProcessInfo::insertTypeInfo(const TypeInfoPtr& typeInfo)
{
    boost::recursive_mutex::scoped_lock l(m_typeInfoLock);

    m_typeInfoMap.insert(std::make_pair(typeInfo->getName(), typeInfo));
}

///////////////////////////////////////////////////////////////////////////////

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
858
void ProcessInfo::insertBreakpoint(BreakpointPtr& breakpoint)
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
859 860 861
{
    boost::recursive_mutex::scoped_lock l(m_breakpointLock);
    
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
862
    m_breakpointMap[breakpoint->getId()] = breakpoint;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
863 864
}

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
865
///////////////////////////////////////////////////////////////////////////////
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
866

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
867
void ProcessInfo::removeBreakpoint(BreakpointPtr& breakpoint)
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
868
{
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
869
    BreakpointPtr origbp;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
870

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
871 872
    {
        boost::recursive_mutex::scoped_lock l(m_breakpointLock);
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
873

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
874 875 876
        BreakpointIdMap::iterator   it = m_breakpointMap.find(breakpoint->getId());
        if (it == m_breakpointMap.end() )
            return;
877

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
878
        origbp = it->second;
879

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
880
        m_breakpointMap.erase(it);
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
881 882
    }

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
883
    BreakpointCallback*  callback = origbp->getCallback();
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
884 885 886
    if ( callback != 0 )
        callback->onRemove();

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
887 888 889
}


SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
890 891
///////////////////////////////////////////////////////////////////////////////

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
892
DebugCallbackResult ProcessInfo::breakpointHit(BreakpointPtr& breakpoint)
893 894
{
    boost::recursive_mutex::scoped_lock l(m_breakpointLock);
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
895 896
    
    BreakpointIdMap::iterator  it =  m_breakpointMap.find( breakpoint->getId() );
897

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
898 899
    if ( it == m_breakpointMap.end() )
        return DebugCallbackNoChange;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
900

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
901
    BreakpointPtr  origBp = it->second;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
902

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
903
    BreakpointCallback*  callback = origBp->getCallback();
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
904
    if ( callback == 0 )
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
905 906
        return DebugCallbackBreak;

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
907
    return callback->onHit();
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
908 909
}

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
910
/////////////////////////////////////////////////////////////////////////////
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
911

912 913 914 915 916 917 918 919 920 921 922 923
void ProcessInfo::onChangeSymbolPaths()
{
    boost::recursive_mutex::scoped_lock l(m_moduleLock);

    for ( ModuleMap::iterator it = m_moduleMap.begin(); it != m_moduleMap.end(); ++it)
    {
        if ( !it->second->isSymbolLoaded() )
            it->second->resetSymbols();
    }
}

/////////////////////////////////////////////////////////////////////////////
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
924

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
925 926
} //namesapce kdlib