routine_tracer.h 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #ifndef __ROUTINE_TRACER_H
  2. #define __ROUTINE_TRACER_H
  3. #include "fixed_types.h"
  4. #include "subsecond_time.h"
  5. #include <deque>
  6. #include <boost/functional/hash.hpp>
  7. // From http://stackoverflow.com/questions/8027368/are-there-no-specializations-of-stdhash-for-standard-containers
  8. namespace std
  9. {
  10. template<typename T>
  11. struct hash<std::deque<T> >
  12. {
  13. size_t operator()(const std::deque<T>& a) const
  14. {
  15. return boost::hash_range(a.begin(), a.end());
  16. }
  17. };
  18. }
  19. class Thread;
  20. typedef std::deque<IntPtr> CallStack;
  21. class RoutineTracerThread
  22. {
  23. public:
  24. RoutineTracerThread(Thread *thread);
  25. virtual ~RoutineTracerThread();
  26. void routineEnter(IntPtr eip, IntPtr esp, IntPtr returnEip);
  27. void routineExit(IntPtr eip, IntPtr esp);
  28. void routineAssert(IntPtr eip, IntPtr esp);
  29. const CallStack& getCallStack() const { return m_stack; }
  30. protected:
  31. Lock m_lock;
  32. Thread *m_thread;
  33. CallStack m_stack;
  34. IntPtr m_last_esp;
  35. private:
  36. bool unwindTo(IntPtr eip);
  37. void routineEnter_unlocked(IntPtr eip, IntPtr esp, IntPtr callEip);
  38. virtual void functionEnter(IntPtr eip, IntPtr callEip) = 0;
  39. virtual void functionExit(IntPtr eip) = 0;
  40. virtual void functionChildEnter(IntPtr eip, IntPtr eip_child) = 0;
  41. virtual void functionChildExit(IntPtr eip, IntPtr eip_child) = 0;
  42. void hookRoiBegin();
  43. void hookRoiEnd();
  44. static SInt64 __hook_roi_begin(UInt64 user, UInt64 arg) { ((RoutineTracerThread*)user)->hookRoiBegin(); return 0; }
  45. static SInt64 __hook_roi_end(UInt64 user, UInt64 arg) { ((RoutineTracerThread*)user)->hookRoiEnd(); return 0; }
  46. };
  47. class RoutineTracer
  48. {
  49. public:
  50. class Routine
  51. {
  52. public:
  53. const IntPtr m_eip;
  54. char *m_name, *m_imgname, *m_filename, *m_location;
  55. IntPtr m_offset;
  56. int m_column, m_line;
  57. Routine(IntPtr eip, const char *name, const char *imgname, IntPtr offset, int column, int line, const char *filename);
  58. void updateLocation(const char *name, const char *imgname, IntPtr offset, int column, int line, const char *filename);
  59. };
  60. static RoutineTracer* create();
  61. RoutineTracer();
  62. virtual ~RoutineTracer();
  63. virtual void addRoutine(IntPtr eip, const char *name, const char *imgname, IntPtr offset, int column, int line, const char *filename) = 0;
  64. virtual bool hasRoutine(IntPtr eip) = 0;
  65. virtual RoutineTracerThread* getThreadHandler(Thread *thread) = 0;
  66. virtual const Routine* getRoutineInfo(IntPtr eip) { return NULL; }
  67. };
  68. #endif // __ROUTINE_TRACER_H