Browse Source

Implement getCallStackFast/Exact for fast call-stack backtrace.

Бранимир Караџић 2 months ago
parent
commit
c8128850f8
9 changed files with 906 additions and 67 deletions
  1. 14 4
      include/bx/debug.h
  2. 4 0
      include/bx/filepath.h
  3. 19 0
      include/bx/inline/string.inl
  4. 9 0
      include/bx/string.h
  5. 1 1
      src/bx.cpp
  6. 838 60
      src/debug.cpp
  7. 6 0
      src/filepath.cpp
  8. 1 1
      tests/run_test.cpp
  9. 14 1
      tests/string_test.cpp

+ 14 - 4
include/bx/debug.h

@@ -49,7 +49,7 @@ namespace bx
 	///
 	WriterI* getDebugOut();
 
-	/// Capture current callstack.
+	/// Capture current callstack fast.
 	///
 	/// @param[in]  _skip Skip top N stack frames.
 	/// @param[in]  _max Maximum frame to capture.
@@ -57,7 +57,17 @@ namespace bx
 	///
 	/// @returns Number of stack frames captured.
 	///
-	uint32_t getCallStack(uint32_t _skip, uint32_t _max, uintptr_t* _outStack);
+	uint32_t getCallStackFast(uint32_t _skip, uint32_t _max, uintptr_t* _outStack);
+
+	/// Capture current callstack with slower but more accurate method.
+	///
+	/// @param[in]  _skip Skip top N stack frames.
+	/// @param[in]  _max Maximum frame to capture.
+	/// @param[out] _outStack Stack frames array. Must be at least `_max` elements.
+	///
+	/// @returns Number of stack frames captured.
+	///
+	uint32_t getCallStackExact(uint32_t _skip, uint32_t _max, uintptr_t* _outStack);
 
 	/// Write callstack.
 	///
@@ -68,9 +78,9 @@ namespace bx
 	///
 	/// @returns Number of bytes writen to `_writer`.
 	///
-	int32_t writeCallstack(WriterI* _writer, uintptr_t* _stack, uint32_t _num, Error* _err);
+	int32_t writeCallstack(WriterI* _writer, const uintptr_t* _stack, uint32_t _num, Error* _err);
 
-	/// Capture call stack, and write it to debug output.
+	/// Capture call stack with `bx::getCallStackExact`, and write it to debug output.
 	///
 	/// @param[in] _skip Skip top N stack frames.
 	///

+ 4 - 0
include/bx/filepath.h

@@ -60,6 +60,10 @@ namespace bx
 		///
 		FilePath(const StringView& _str);
 
+		/// Assign file path from string.
+		///
+		FilePath& operator=(const char* _rhs);
+
 		/// Assign file path from string.
 		///
 		FilePath& operator=(const StringView& _rhs);

+ 19 - 0
include/bx/inline/string.inl

@@ -187,6 +187,25 @@ namespace bx
 		return m_0terminated;
 	}
 
+	inline bool operator==(const StringView& _lhs, const StringView& _rhs)
+	{
+		return 0 == strCmp(_lhs, _rhs);
+	}
+
+	inline bool overlap(const StringView& _a, const StringView& _b)
+	{
+		return _a.getTerm() > _b.getPtr()
+			&& _b.getTerm() > _a.getPtr()
+			;
+	}
+
+	inline bool contain(const StringView& _a, const StringView& _b)
+	{
+		return _a.getPtr()  <= _b.getPtr()
+			&& _a.getTerm() >= _b.getTerm()
+			;
+	}
+
 	template<uint16_t MaxCapacityT>
 	inline FixedStringT<MaxCapacityT>::FixedStringT()
 		: m_len(0)

+ 9 - 0
include/bx/string.h

@@ -137,6 +137,15 @@ namespace bx
 		bool        m_0terminated;
 	};
 
+	/// Compare two string views.
+	bool operator==(const StringView& _lhs, const StringView& _rhs);
+
+	/// Returns true if two string views overlap.
+	bool overlap(const StringView& _a, const StringView& _b);
+
+	/// Returns true if string view `_a` contains string view `_b`.
+	bool contain(const StringView& _a, const StringView& _b);
+
 	/// Fixed capacity string.
 	///
 	template<uint16_t MaxCapacityT>

+ 1 - 1
src/bx.cpp

@@ -42,7 +42,7 @@ namespace bx
 		total += write(&smb, "\n\n", &err);
 
 		uintptr_t stack[32];
-		const uint32_t num = getCallStack(2 /* skip self */ + _skip, BX_COUNTOF(stack), stack);
+		const uint32_t num = getCallStackExact(2 /* skip self */ + _skip, BX_COUNTOF(stack), stack);
 		total += writeCallstack(&smb, stack, num, &err);
 
 		total += write(&smb, &err,

File diff suppressed because it is too large
+ 838 - 60
src/debug.cpp


+ 6 - 0
src/filepath.cpp

@@ -303,6 +303,12 @@ namespace bx
 		set(_filePath);
 	}
 
+	FilePath& FilePath::operator=(const char* _rhs)
+	{
+		set(_rhs);
+		return *this;
+	}
+
 	FilePath& FilePath::operator=(const StringView& _rhs)
 	{
 		set(_rhs);

+ 1 - 1
tests/run_test.cpp

@@ -19,7 +19,7 @@ bool testAssertHandler(const bx::Location& _location, uint32_t _skip, const char
 	bx::printf("\n");
 
 	uintptr_t stack[32];
-	const uint32_t num = bx::getCallStack(2 /* skip self */ + _skip, BX_COUNTOF(stack), stack);
+	const uint32_t num = bx::getCallStackExact(2 /* skip self */ + _skip, BX_COUNTOF(stack), stack);
 	bx::writeCallstack(bx::getStdOut(), stack, num, bx::ErrorIgnore{});
 
 	// Throwing exceptions is required for testing asserts being trigged.

+ 14 - 1
tests/string_test.cpp

@@ -45,7 +45,7 @@ TEST_CASE("StringLiteral", "[string]")
 
 	REQUIRE(5 == sv.getLength() );
 	REQUIRE(5 == bx::strLen(sv) );
-	REQUIRE(0 == bx::strCmp("abvgd", sv) );
+	REQUIRE("abvgd" == sv);
 }
 
 TEST_CASE("stringPrintfTy", "[string]")
@@ -218,6 +218,19 @@ TEST_CASE("strCmpV sort", "[string][sort]")
 	}
 }
 
+TEST_CASE("overlap", "[string]")
+{
+	const char* test = "The Quick Brown Fox Jumps Over The Lazy Dog.";
+
+	const bx::StringView quick = bx::strFind(test, "Quick");
+
+	REQUIRE(bx::overlap(quick, test) );
+
+	const bx::StringView empty;
+	REQUIRE(!bx::overlap(quick, empty) );
+	REQUIRE(!bx::overlap(test, empty) );
+}
+
 TEST_CASE("strRFind", "[string]")
 {
 	const char* test = "test";

Some files were not shown because too many files changed in this diff