From de6e7d2fc3e67c149f9abc9c47d1f73db56f91bc Mon Sep 17 00:00:00 2001 From: Tiago Rodrigues Date: Fri, 24 Nov 2023 20:48:39 -0500 Subject: [PATCH] move the symbol resolving functionality to the update application instead of creating a new one --- manual/tracy.tex | 8 +- tracy-edit/build/unix/Makefile | 16 - tracy-edit/build/unix/build.mk | 12 - tracy-edit/build/unix/debug.mk | 6 - tracy-edit/build/unix/release.mk | 9 - tracy-edit/build/win32/tracy-edit.sln | 25 -- tracy-edit/build/win32/tracy-edit.vcxproj | 210 ---------- .../build/win32/tracy-edit.vcxproj.filters | 366 ------------------ tracy-edit/src/tracy-edit.cpp | 213 ---------- update/build/win32/update.vcxproj | 8 +- update/build/win32/update.vcxproj.filters | 12 + .../src/OfflineSymbolResolver.cpp | 51 ++- .../src/OfflineSymbolResolver.h | 5 +- .../src/OfflineSymbolResolverAddr2Line.cpp | 0 .../src/OfflineSymbolResolverDbgHelper.cpp | 0 update/src/update.cpp | 25 +- 16 files changed, 90 insertions(+), 876 deletions(-) delete mode 100644 tracy-edit/build/unix/Makefile delete mode 100644 tracy-edit/build/unix/build.mk delete mode 100644 tracy-edit/build/unix/debug.mk delete mode 100644 tracy-edit/build/unix/release.mk delete mode 100644 tracy-edit/build/win32/tracy-edit.sln delete mode 100644 tracy-edit/build/win32/tracy-edit.vcxproj delete mode 100644 tracy-edit/build/win32/tracy-edit.vcxproj.filters delete mode 100644 tracy-edit/src/tracy-edit.cpp rename {tracy-edit => update}/src/OfflineSymbolResolver.cpp (71%) rename {tracy-edit => update}/src/OfflineSymbolResolver.h (71%) rename {tracy-edit => update}/src/OfflineSymbolResolverAddr2Line.cpp (100%) rename {tracy-edit => update}/src/OfflineSymbolResolverDbgHelper.cpp (100%) diff --git a/manual/tracy.tex b/manual/tracy.tex index 766f7d06..c11cb55d 100644 --- a/manual/tracy.tex +++ b/manual/tracy.tex @@ -1792,12 +1792,12 @@ As an alternative to to runtime symbol resolution, we can set the environment va the minimal set of info required for offline resolution (a shared library path and an offset into that shared library). The generated tracy capture will have callstack frames symbols showing \texttt{[unresolved]}. -The \texttt{tracy-edit} tool can be used to load that capture, perform symbol resolution offline +The \texttt{update} tool can be used to load that capture, perform symbol resolution offline (by passing \texttt{-r}) and writing out a new capture with symbols resolved. -By default \texttt{tracy-edit} will use the original shared libraries paths that were recorded +By default \texttt{update} will use the original shared libraries paths that were recorded in the capture (which assumes running in the same machine or a machine with identical filesystem setup as the one used to run the tracy instrumented application). - You can do path substitution with the \texttt{-s} option to perform any number of path + You can do path substitution with the \texttt{-p} option to perform any number of path substitions in order to use symbols located elsewhere. \begin{bclogo}[ @@ -1805,7 +1805,7 @@ noborder=true, couleur=black!5, logo=\bcbombe ]{Important} -Beware that \texttt{tracy-edit} will use any matching symbol file to the path it resolved to (no symbol version checking is done), so if the symbol file doesn't match the code that was used when doing the callstack capturing you will get incorrect results. +Beware that \texttt{update} will use any matching symbol file to the path it resolved to (no symbol version checking is done), so if the symbol file doesn't match the code that was used when doing the callstack capturing you will get incorrect results. \end{bclogo} \subsection{Lua support} diff --git a/tracy-edit/build/unix/Makefile b/tracy-edit/build/unix/Makefile deleted file mode 100644 index 035eda1b..00000000 --- a/tracy-edit/build/unix/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -all: release - -debug: - @+make -f debug.mk all - -release: - @+make -f release.mk all - -clean: - @+make -f build.mk clean - -db: clean - @bear -- $(MAKE) -f debug.mk all - @mv -f compile_commands.json ../../../ - -.PHONY: all clean debug release db diff --git a/tracy-edit/build/unix/build.mk b/tracy-edit/build/unix/build.mk deleted file mode 100644 index 85fb7528..00000000 --- a/tracy-edit/build/unix/build.mk +++ /dev/null @@ -1,12 +0,0 @@ -CFLAGS += -CXXFLAGS := $(CFLAGS) -std=gnu++17 -DEFINES += -DTRACY_NO_STATISTICS -INCLUDES := $(shell pkg-config --cflags capstone) -LIBS += $(shell pkg-config --libs capstone) -lpthread -PROJECT := tracy-edit -IMAGE := $(PROJECT)-$(BUILD) - -FILTER := -include ../../../common/src-from-vcxproj.mk - -include ../../../common/unix.mk diff --git a/tracy-edit/build/unix/debug.mk b/tracy-edit/build/unix/debug.mk deleted file mode 100644 index a4ec6b6a..00000000 --- a/tracy-edit/build/unix/debug.mk +++ /dev/null @@ -1,6 +0,0 @@ -CFLAGS := -g3 -Wall -DEFINES := -DDEBUG -BUILD := debug - -include ../../../common/unix-debug.mk -include build.mk diff --git a/tracy-edit/build/unix/release.mk b/tracy-edit/build/unix/release.mk deleted file mode 100644 index ccf07661..00000000 --- a/tracy-edit/build/unix/release.mk +++ /dev/null @@ -1,9 +0,0 @@ -CFLAGS := -O3 -ifndef TRACY_NO_LTO -CFLAGS += -flto -endif -DEFINES := -DNDEBUG -BUILD := release - -include ../../../common/unix-release.mk -include build.mk diff --git a/tracy-edit/build/win32/tracy-edit.sln b/tracy-edit/build/win32/tracy-edit.sln deleted file mode 100644 index 9b606fbc..00000000 --- a/tracy-edit/build/win32/tracy-edit.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30907.101 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tracy-edit", "tracy-edit.vcxproj", "{447D58BF-94CD-4469-BB90-549C05D03E00}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {447D58BF-94CD-4469-BB90-549C05D03E00}.Debug|x64.ActiveCfg = Debug|x64 - {447D58BF-94CD-4469-BB90-549C05D03E00}.Debug|x64.Build.0 = Debug|x64 - {447D58BF-94CD-4469-BB90-549C05D03E00}.Release|x64.ActiveCfg = Release|x64 - {447D58BF-94CD-4469-BB90-549C05D03E00}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {3E51386C-43EA-44AC-9F24-AFAFE4D63ADE} - EndGlobalSection -EndGlobal diff --git a/tracy-edit/build/win32/tracy-edit.vcxproj b/tracy-edit/build/win32/tracy-edit.vcxproj deleted file mode 100644 index 2fb58ced..00000000 --- a/tracy-edit/build/win32/tracy-edit.vcxproj +++ /dev/null @@ -1,210 +0,0 @@ - - - - - Debug - x64 - - - Release - x64 - - - - 15.0 - {447D58BF-94CD-4469-BB90-549C05D03E00} - tracy-edit - 10.0.17763.0 - x64-windows-static - - - - Application - true - v143 - MultiByte - - - Application - false - v143 - true - MultiByte - - - - - - - - - - - - - - - - true - - - - Level3 - Disabled - true - true - true - TRACY_NO_STATISTICS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;NOMINMAX;_USE_MATH_DEFINES;%(PreprocessorDefinitions) - AdvancedVectorExtensions2 - stdcpplatest - $(ProjectDir)..\..\..\vcpkg_installed\$(VcpkgTriplet)\include;$(ProjectDir)..\..\..\vcpkg_installed\$(VcpkgTriplet)\include\capstone;$(VcpkgManifestRoot)\vcpkg_installed\$(VcpkgTriplet)\$(VcpkgTriplet)\include\capstone;$(VcpkgRoot)\installed\$(VcpkgTriplet)\include\capstone - - - ws2_32.lib;capstone.lib;dbghelp.lib;%(AdditionalDependencies) - Console - $(ProjectDir)..\..\..\vcpkg_installed\$(VcpkgTriplet)\debug\lib - - - - - Level3 - MaxSpeed - true - true - true - true - true - TRACY_NO_STATISTICS;NDEBUG;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;NOMINMAX;_USE_MATH_DEFINES;%(PreprocessorDefinitions) - AdvancedVectorExtensions2 - stdcpplatest - $(ProjectDir)..\..\..\vcpkg_installed\$(VcpkgTriplet)\include;$(ProjectDir)..\..\..\vcpkg_installed\$(VcpkgTriplet)\include\capstone;$(VcpkgManifestRoot)\vcpkg_installed\$(VcpkgTriplet)\$(VcpkgTriplet)\include\capstone;$(VcpkgRoot)\installed\$(VcpkgTriplet)\include\capstone - - - true - true - ws2_32.lib;capstone.lib;dbghelp.lib;%(AdditionalDependencies) - Console - $(ProjectDir)..\..\..\vcpkg_installed\$(VcpkgTriplet)\lib - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tracy-edit/build/win32/tracy-edit.vcxproj.filters b/tracy-edit/build/win32/tracy-edit.vcxproj.filters deleted file mode 100644 index 8b77d3ab..00000000 --- a/tracy-edit/build/win32/tracy-edit.vcxproj.filters +++ /dev/null @@ -1,366 +0,0 @@ - - - - - {729c80ee-4d26-4a5e-8f1f-6c075783eb56} - - - {cf23ef7b-7694-4154-830b-00cf053350ea} - - - {e39d3623-47cd-4752-8da9-3ea324f964c1} - - - {9ec18988-3ab7-4c05-a9d0-46c0a68037de} - - - {5ee9ba63-2914-4027-997e-e743a294bba6} - - - {a166d032-7be0-4d07-9f85-a8199cc1ec7c} - - - {438fff23-197c-4b6f-91f0-74f8b3878571} - - - {e5c7021a-e0e4-45c2-b461-e806bc036d5f} - - - - - server - - - server - - - src - - - server - - - server - - - server - - - server - - - zstd\common - - - zstd\common - - - zstd\common - - - zstd\common - - - zstd\common - - - zstd\common - - - zstd\common - - - zstd\common - - - zstd\compress - - - zstd\compress - - - zstd\compress - - - zstd\compress - - - zstd\compress - - - zstd\compress - - - zstd\compress - - - zstd\compress - - - zstd\compress - - - zstd\compress - - - zstd\compress - - - zstd\compress - - - zstd\compress - - - zstd\decompress - - - zstd\decompress - - - zstd\decompress - - - zstd\decompress - - - zstd\dictBuilder - - - zstd\dictBuilder - - - zstd\dictBuilder - - - zstd\dictBuilder - - - common - - - common - - - common - - - common - - - common - - - src - - - src - - - src - - - - - - server - - - server - - - server - - - server - - - server - - - server - - - server - - - server - - - server - - - server - - - server - - - server - - - server - - - zstd - - - zstd - - - zstd\common - - - zstd\common - - - zstd\common - - - zstd\common - - - zstd\common - - - zstd\common - - - zstd\common - - - zstd\common - - - zstd\common - - - zstd\common - - - zstd\common - - - zstd\common - - - zstd\common - - - zstd\common - - - zstd\compress - - - zstd\compress - - - zstd\compress - - - zstd\compress - - - zstd\compress - - - zstd\compress - - - zstd\compress - - - zstd\compress - - - zstd\compress - - - zstd\compress - - - zstd\compress - - - zstd\compress - - - zstd\compress - - - zstd\decompress - - - zstd\decompress - - - zstd\decompress - - - zstd - - - zstd\dictBuilder - - - zstd\dictBuilder - - - zstd\common - - - zstd\compress - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - - - zstd\decompress - - - \ No newline at end of file diff --git a/tracy-edit/src/tracy-edit.cpp b/tracy-edit/src/tracy-edit.cpp deleted file mode 100644 index f79c5dab..00000000 --- a/tracy-edit/src/tracy-edit.cpp +++ /dev/null @@ -1,213 +0,0 @@ -#ifdef _WIN32 -# include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include "../../server/TracyFileRead.hpp" -#include "../../server/TracyFileWrite.hpp" -#include "../../server/TracyWorker.hpp" -#include "../../getopt/getopt.h" - -#include "OfflineSymbolResolver.h" - -struct Args -{ - const char* inputTracyPath = nullptr; - const char* outputTracyPath = nullptr; - bool verbose = false; - bool resolveSymbols = false; - std::vector pathSubstitutions; - tracy::FileWrite::Compression compressionType = tracy::FileWrite::Compression::Zstd; - int compressionLevel = 5; -}; - -void PrintUsageAndExit() -{ - std::cerr << "Modify a tracy file" << std::endl; - std::cerr << "Usage:" << std::endl; - std::cerr << " tracy-edit [OPTION...] " << std::endl; - std::cerr << std::endl; - std::cerr << " -h, --help Print usage" << std::endl; - std::cerr << " -v, --verbose Enable verbose logging" << std::endl; - std::cerr << " -r, --resolveSymbols Resolve symbols and patch callstack frames" << std::endl; - std::cerr << " -s, --substitutePath \"REGEX_MATCH;REPLACEMENT\" Substitute symbol resolution path with an alternative" << std::endl; - std::cerr << " -c, --compression Type Set the compression algorithm used for the output [Fast,Slow,Extreme,Zstd]" << std::endl; - std::cerr << " -l, --compressesionLevel Level Level of compression" << std::endl; - exit( 1 ); -} - -static const char* compressionTypeStr[] -{ - "Fast", - "Slow", - "Extreme", - "Zstd" -}; -static_assert( uint32_t(tracy::FileWrite::Compression::Zstd)+1 == sizeof(compressionTypeStr)/sizeof(compressionTypeStr[0])); -tracy::FileWrite::Compression getCompressionFromString(const char* str) -{ - for( uint32_t i = 0; i < sizeof(compressionTypeStr)/sizeof(compressionTypeStr[0]); ++i ) - { - if( strcmp( compressionTypeStr[i], str ) == 0 ) - { - return tracy::FileWrite::Compression( i ); - } - } - return tracy::FileWrite::Compression::Zstd; -} - -Args ParseArgs( int argc, char** argv ) -{ - if ( argc < 3 ) - { - PrintUsageAndExit(); - } - - Args args; - - struct option long_opts[] = - { - { "help", no_argument, NULL, 'h' }, - { "verbose", no_argument, NULL, 'v' }, - { "resolveSymbols", no_argument, NULL, 'r' }, - { "substitutePath", required_argument, NULL, 's' }, - { "compression", required_argument, NULL, 'c' }, - { "compressesionLevel", required_argument, NULL, 'l' }, - { NULL, 0, NULL, 0 } - }; - - int c; - while ( (c = getopt_long( argc, argv, "hvrc:l:s:", long_opts, NULL )) != -1 ) - { - switch (c) - { - case 'h': - PrintUsageAndExit(); - break; - case 'v': - args.verbose = true; - break; - case 'r': - args.resolveSymbols = true; - break; - case 'c': - args.compressionType = getCompressionFromString( optarg ); - break; - case 's': - args.pathSubstitutions.push_back( optarg ); - break; - case 'l': - args.compressionLevel = atoi( optarg ); - break; - default: - PrintUsageAndExit(); - break; - } - } - - if (argc != optind + 2) - { - PrintUsageAndExit(); - } - - args.inputTracyPath = argv[optind + 0]; - args.outputTracyPath = argv[optind + 1]; - - return args; -} - -void PatchSymbols(tracy::Worker& worker, const Args& args); - -int main( int argc, char** argv ) -{ -#ifdef _WIN32 - if( !AttachConsole( ATTACH_PARENT_PROCESS ) ) - { - AllocConsole(); - SetConsoleMode( GetStdHandle( STD_OUTPUT_HANDLE ), 0x07 ); - } -#endif // #ifdef _WIN32 - - Args args = ParseArgs( argc, argv ); - - // load input tracy file - auto f = std::unique_ptr(tracy::FileRead::Open( args.inputTracyPath )); - if (!f) - { - std::cerr << "Could not open file: " << args.inputTracyPath; - return 1; - } - - std::cout << "Reading ..." << std::endl; - - const bool allowBgThreads = false; - bool allowStringModification = true; - tracy::Worker worker( *f, tracy::EventType::All, allowBgThreads, allowStringModification ); - - std::cout << "Loaded." << std::endl; - - if(args.resolveSymbols) - { - PatchSymbols(worker, args); - } - - // save out capture file with new compression options - std::cout << "Saving (using '" << compressionTypeStr[uint32_t(args.compressionType)] - << "', level: " << args.compressionLevel << ") ..." << std::endl; - - auto w = std::unique_ptr( - tracy::FileWrite::Open( args.outputTracyPath, args.compressionType, args.compressionLevel) ); - if( !w ) - { - std::cerr << "Cannot open output file: '" << args.outputTracyPath << "'" << std::endl; - exit( 1 ); - } - - worker.Write( *w, false ); - - std::cout << "Cleanup..." << std::endl; - - return 0; -} - -void PatchSymbols( tracy::Worker& worker, const Args& args ) -{ - std::cout << "Resolving and patching symbols..." << std::endl; - - PathSubstitutionList pathSubstitutionList; - for( const std::string& pathSubst : args.pathSubstitutions ) - { - std::size_t pos = pathSubst.find(';'); - if( pos == std::string::npos ) - { - std::cerr << "Ignoring invalid path substitution: '" << pathSubst - << " '(please separate the regex of the string to replace with a ';')" << std::endl; - continue; - } - - try - { - std::regex reg( pathSubst.substr(0, pos) ); - std::string replacementStr( pathSubst.substr(pos + 1) ); - pathSubstitutionList.push_back( std::pair(reg, replacementStr) ); - } - catch( std::exception& e ) - { - std::cerr << "Ignoring invalid path substitution: '" << pathSubst - << "' (" << e.what() << ")" << std::endl; - continue; - } - } - - if( !PatchSymbols( worker, pathSubstitutionList, args.verbose ) ) - { - std::cerr << "Failed to patch symbols" << std::endl; - } -} diff --git a/update/build/win32/update.vcxproj b/update/build/win32/update.vcxproj index 55f0e55e..1ed9c723 100644 --- a/update/build/win32/update.vcxproj +++ b/update/build/win32/update.vcxproj @@ -60,7 +60,7 @@ $(ProjectDir)..\..\..\vcpkg_installed\$(VcpkgTriplet)\include;$(ProjectDir)..\..\..\vcpkg_installed\$(VcpkgTriplet)\include\capstone;$(VcpkgManifestRoot)\vcpkg_installed\$(VcpkgTriplet)\$(VcpkgTriplet)\include\capstone;$(VcpkgRoot)\installed\$(VcpkgTriplet)\include\capstone - ws2_32.lib;capstone.lib;%(AdditionalDependencies) + ws2_32.lib;capstone.lib;dbghelp.lib;%(AdditionalDependencies) Console $(ProjectDir)..\..\..\vcpkg_installed\$(VcpkgTriplet)\debug\lib @@ -82,7 +82,7 @@ true true - ws2_32.lib;capstone.lib;%(AdditionalDependencies) + ws2_32.lib;capstone.lib;dbghelp.lib;%(AdditionalDependencies) Console $(ProjectDir)..\..\..\vcpkg_installed\$(VcpkgTriplet)\lib @@ -130,6 +130,9 @@ + + + @@ -200,6 +203,7 @@ + diff --git a/update/build/win32/update.vcxproj.filters b/update/build/win32/update.vcxproj.filters index c987fbf6..7c90bef3 100644 --- a/update/build/win32/update.vcxproj.filters +++ b/update/build/win32/update.vcxproj.filters @@ -159,6 +159,15 @@ common + + src + + + src + + + src + @@ -362,6 +371,9 @@ common + + src + diff --git a/tracy-edit/src/OfflineSymbolResolver.cpp b/update/src/OfflineSymbolResolver.cpp similarity index 71% rename from tracy-edit/src/OfflineSymbolResolver.cpp rename to update/src/OfflineSymbolResolver.cpp index 9ba7ce71..08be4d52 100644 --- a/tracy-edit/src/OfflineSymbolResolver.cpp +++ b/update/src/OfflineSymbolResolver.cpp @@ -11,13 +11,13 @@ #include "OfflineSymbolResolver.h" -bool ApplyPathSubstitutions( std::string& path, const PathSubstitutionList& pathSubstituionlist ) +bool ApplyPathSubstitutions( std::string& path, const PathSubstitutionList& pathSubstitutionlist ) { - for( const auto& substituion : pathSubstituionlist ) + for( const auto& substitution : pathSubstitutionlist ) { - if( std::regex_match(path, substituion.first) ) + if( std::regex_match(path, substitution.first) ) { - path = std::regex_replace( path, substituion.first, substituion.second ); + path = std::regex_replace( path, substitution.first, substitution.second ); return true; } } @@ -31,12 +31,12 @@ tracy::StringIdx AddSymbolString( tracy::Worker& worker, const std::string& str return tracy::StringIdx( location.idx ); } -bool PatchSymbols( tracy::Worker& worker, const PathSubstitutionList& pathSubstituionlist, bool verbose ) +bool PatchSymbolsWithRegex( tracy::Worker& worker, const PathSubstitutionList& pathSubstitutionlist, bool verbose ) { uint64_t callstackFrameCount = worker.GetCallstackFrameCount(); std::string relativeSoNameMatch = "[unresolved]"; - std::cout << "Found '" << callstackFrameCount << "' callstack frames. Batching into image groups..." << std::endl; + std::cout << "Found " << callstackFrameCount << " callstack frames. Batching into image groups..." << std::endl; // batch the symbol queries by .so so we issue the least amount of requests using FrameEntriesPerImageIdx = std::unordered_map; @@ -72,7 +72,7 @@ bool PatchSymbols( tracy::Worker& worker, const PathSubstitutionList& pathSubsti } } - std::cout << "Batched into '" << entriesPerImageIdx.size() << "' unique image groups" << std::endl; + std::cout << "Batched into " << entriesPerImageIdx.size() << " unique image groups" << std::endl; // FIXME: the resolving of symbols here can be slow and could be done in parallel per "image" // - be careful with string allocation though as that would be not safe to do in parallel @@ -88,7 +88,7 @@ bool PatchSymbols( tracy::Worker& worker, const PathSubstitutionList& pathSubsti std::cout << "Resolving " << entries.size() << " symbols for image: '" << imagePath << "'" << std::endl; - const bool substituted = ApplyPathSubstitutions( imagePath, pathSubstituionlist ); + const bool substituted = ApplyPathSubstitutions( imagePath, pathSubstitutionlist ); if( substituted ) { std::cout << "\tPath substituted to: '" << imagePath << "'" << std::endl; @@ -134,3 +134,38 @@ bool PatchSymbols( tracy::Worker& worker, const PathSubstitutionList& pathSubsti return true; } + +void PatchSymbols( tracy::Worker& worker, const std::vector& pathSubstitutionsStrings, bool verbose ) +{ + std::cout << "Resolving and patching symbols..." << std::endl; + + PathSubstitutionList pathSubstitutionList; + for ( const std::string& pathSubst : pathSubstitutionsStrings ) + { + std::size_t pos = pathSubst.find(';'); + if ( pos == std::string::npos ) + { + std::cerr << "Ignoring invalid path substitution: '" << pathSubst + << " '(please separate the regex of the string to replace with a ';')" << std::endl; + continue; + } + + try + { + std::regex reg(pathSubst.substr(0, pos)); + std::string replacementStr(pathSubst.substr(pos + 1)); + pathSubstitutionList.push_back(std::pair(reg, replacementStr)); + } + catch ( std::exception& e ) + { + std::cerr << "Ignoring invalid path substitution: '" << pathSubst + << "' (" << e.what() << ")" << std::endl; + continue; + } + } + + if ( !PatchSymbolsWithRegex(worker, pathSubstitutionList, verbose) ) + { + std::cerr << "Failed to patch symbols" << std::endl; + } +} \ No newline at end of file diff --git a/tracy-edit/src/OfflineSymbolResolver.h b/update/src/OfflineSymbolResolver.h similarity index 71% rename from tracy-edit/src/OfflineSymbolResolver.h rename to update/src/OfflineSymbolResolver.h index d61863dd..e3216eb5 100644 --- a/tracy-edit/src/OfflineSymbolResolver.h +++ b/update/src/OfflineSymbolResolver.h @@ -32,8 +32,9 @@ using SymbolEntryList = std::vector; bool ResolveSymbols( const std::string& imagePath, const FrameEntryList& inputEntryList, SymbolEntryList& resolvedEntries ); -using PathSubstitutionList = std::vector >; +void PatchSymbols( tracy::Worker& worker, const std::vector& pathSubstitutionsStrings, bool verbose = false ); -bool PatchSymbols( tracy::Worker& worker, const PathSubstitutionList& pathSubstituionlist, bool verbose = false ); +using PathSubstitutionList = std::vector >; +bool PatchSymbolsWithRegex( tracy::Worker& worker, const PathSubstitutionList& pathSubstituionlist, bool verbose = false ); #endif // __SYMBOLRESOLVER_HPP__ \ No newline at end of file diff --git a/tracy-edit/src/OfflineSymbolResolverAddr2Line.cpp b/update/src/OfflineSymbolResolverAddr2Line.cpp similarity index 100% rename from tracy-edit/src/OfflineSymbolResolverAddr2Line.cpp rename to update/src/OfflineSymbolResolverAddr2Line.cpp diff --git a/tracy-edit/src/OfflineSymbolResolverDbgHelper.cpp b/update/src/OfflineSymbolResolverDbgHelper.cpp similarity index 100% rename from tracy-edit/src/OfflineSymbolResolverDbgHelper.cpp rename to update/src/OfflineSymbolResolverDbgHelper.cpp diff --git a/update/src/update.cpp b/update/src/update.cpp index f3cba1b7..1643c620 100644 --- a/update/src/update.cpp +++ b/update/src/update.cpp @@ -15,6 +15,8 @@ #include "../../zstd/zstd.h" #include "../../getopt/getopt.h" +#include "OfflineSymbolResolver.h" + #ifdef __APPLE__ # define ftello64(x) ftello(x) #elif defined _WIN32 @@ -32,6 +34,9 @@ void Usage() printf( " l: locks, m: messages, p: plots, M: memory, i: frame images\n" ); printf( " c: context switches, s: sampling data, C: symbol code, S: source cache\n" ); printf( " -c: scan for source files missing in cache and add if found\n" ); + printf( " -r resolve symbols and patch callstack frames\n"); + printf( " -p: substitute symbol resolution path with an alternative: \"REGEX_MATCH;REPLACEMENT\"\n"); + exit( 1 ); } @@ -50,8 +55,11 @@ int main( int argc, char** argv ) int zstdLevel = 1; bool buildDict = false; bool cacheSource = false; + bool resolveSymbols = false; + std::vector pathSubstitutions; + int c; - while( ( c = getopt( argc, argv, "hez:ds:c" ) ) != -1 ) + while( ( c = getopt( argc, argv, "hez:ds:crp:" ) ) != -1 ) { switch( c ) { @@ -118,12 +126,19 @@ int main( int argc, char** argv ) case 'c': cacheSource = true; break; + case 'r': + resolveSymbols = true; + break; + case 'p': + pathSubstitutions.push_back(optarg); + break; default: Usage(); break; } } - if( argc - optind != 2 ) Usage(); + + if (argc != optind + 2) Usage(); const char* input = argv[optind]; const char* output = argv[optind+1]; @@ -144,7 +159,9 @@ int main( int argc, char** argv ) int inVer; { const auto t0 = std::chrono::high_resolution_clock::now(); - tracy::Worker worker( *f, (tracy::EventType::Type)events, false ); + const bool allowBgThreads = false; + const bool allowStringModification = resolveSymbols; + tracy::Worker worker( *f, (tracy::EventType::Type)events, allowBgThreads, allowStringModification); #ifndef TRACY_NO_STATISTICS while( !worker.AreSourceLocationZonesReady() ) std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) ); @@ -152,6 +169,8 @@ int main( int argc, char** argv ) if( cacheSource ) worker.CacheSourceFiles(); + if ( resolveSymbols ) PatchSymbols( worker, pathSubstitutions ); + auto w = std::unique_ptr( tracy::FileWrite::Open( output, clev, zstdLevel ) ); if( !w ) {