| 726 | }; |
| 727 | |
| 728 | class StackTraceImplBase { |
| 729 | public: |
| 730 | StackTraceImplBase() |
| 731 | : _thread_id(0), _skip(0), _context(nullptr), _error_addr(nullptr) {} |
| 732 | |
| 733 | size_t thread_id() const { return _thread_id; } |
| 734 | |
| 735 | void skip_n_firsts(size_t n) { _skip = n; } |
| 736 | |
| 737 | protected: |
| 738 | void load_thread_info() { |
| 739 | #ifdef BACKWARD_SYSTEM_LINUX |
| 740 | #ifndef __ANDROID__ |
| 741 | _thread_id = static_cast<size_t>(syscall(SYS_gettid)); |
| 742 | #else |
| 743 | _thread_id = static_cast<size_t>(gettid()); |
| 744 | #endif |
| 745 | if (_thread_id == static_cast<size_t>(getpid())) { |
| 746 | // If the thread is the main one, let's hide that. |
| 747 | // I like to keep little secret sometimes. |
| 748 | _thread_id = 0; |
| 749 | } |
| 750 | #elif defined(BACKWARD_SYSTEM_DARWIN) |
| 751 | _thread_id = reinterpret_cast<size_t>(pthread_self()); |
| 752 | if (pthread_main_np() == 1) { |
| 753 | // If the thread is the main one, let's hide that. |
| 754 | _thread_id = 0; |
| 755 | } |
| 756 | #endif |
| 757 | } |
| 758 | |
| 759 | void set_context(void *context) { _context = context; } |
| 760 | void *context() const { return _context; } |
| 761 | |
| 762 | void set_error_addr(void *error_addr) { _error_addr = error_addr; } |
| 763 | void *error_addr() const { return _error_addr; } |
| 764 | |
| 765 | size_t skip_n_firsts() const { return _skip; } |
| 766 | |
| 767 | private: |
| 768 | size_t _thread_id; |
| 769 | size_t _skip; |
| 770 | void *_context; |
| 771 | void *_error_addr; |
| 772 | }; |
| 773 | |
| 774 | class StackTraceImplHolder : public StackTraceImplBase { |
| 775 | public: |
nothing calls this directly
no outgoing calls
no test coverage detected