├── .appveyor.yml ├── .editorconfig ├── .gitattributes ├── .gitignore ├── .gitmodules ├── LICENSE ├── README.md ├── _config.yml ├── img ├── mtuner.png └── mtuner_screenshot.png ├── makefile ├── scripts ├── MTunerBuildSDKSony.bat ├── MTunerGenerateOSX.sh ├── MTunerGenerateVS2022sln.bat └── MTunerPack.bat └── src └── MTuner ├── genie ├── MTuner.lua └── genie.lua ├── resources ├── fonts │ ├── Maven Pro Bold.otf │ ├── Maven Pro Medium.otf │ └── Maven Pro Regular.otf ├── icon256.png ├── icons │ ├── Icon256.ico │ ├── Icon64.ico │ ├── favicon_16x16.ico │ └── favicon_32x32.ico └── images │ ├── Documentation.png │ ├── Editor64.png │ ├── Filter64.png │ ├── Flame64.png │ ├── FlameSelected64.png │ ├── Graph128.png │ ├── Graph256.png │ ├── Graph64.png │ ├── Graph64_hover.png │ ├── Group64.png │ ├── GroupSelected64.png │ ├── Heaps.png │ ├── Histogram64.png │ ├── Icon128.png │ ├── Icon256.png │ ├── Icon64.png │ ├── Leak64.png │ ├── LeakSelected64.png │ ├── List64.png │ ├── ListSelected64.png │ ├── Lupa16.png │ ├── Open64.png │ ├── Projects64.png │ ├── Run.png │ ├── StackTraceSource64.png │ ├── StackTree64.png │ ├── StackTreeSelected64.png │ ├── Symbol64.png │ ├── TreeMap64.png │ ├── TreeMapSelected64.png │ ├── dock_close.png │ ├── dock_close_hover.png │ ├── dock_detach.png │ ├── dock_detach_hover.png │ ├── gnu64.png │ ├── link64_active.png │ ├── link64_inactive.png │ ├── linkedin.png │ ├── logo.png │ ├── modules128.png │ ├── modules64.png │ ├── notok.png │ ├── ok.png │ ├── red_dot.png │ ├── table.png │ ├── toolchain_android_arm.png │ ├── toolchain_android_mips.png │ ├── toolchain_android_x86.png │ ├── toolchain_mingw.png │ ├── toolchain_ps3.png │ ├── toolchain_ps4.png │ ├── toolchain_ps5.png │ ├── toolchain_switch.png │ └── twitter.png └── src ├── MTuner_pch.cpp ├── MTuner_pch.h ├── about.cpp ├── about.h ├── about.ui ├── bigtable.cpp ├── bigtable.h ├── bigtable.ui ├── bigtabletablewidget.h ├── binloaderview.cpp ├── binloaderview.h ├── binloaderview.ui ├── capturecontext.cpp ├── capturecontext.h ├── centralwidget.cpp ├── centralwidget.h ├── centralwidget.ui ├── env_var.cpp ├── env_var.h ├── env_var.ui ├── environment.cpp ├── environment.h ├── environment.ui ├── external_editor.cpp ├── external_editor.h ├── external_editor.ui ├── gcc.cpp ├── gcc.h ├── gcc.ui ├── graph.cpp ├── graph.h ├── graph.ui ├── graphcurve.cpp ├── graphcurve.h ├── graphgrid.cpp ├── graphgrid.h ├── graphmarkers.cpp ├── graphmarkers.h ├── graphselect.cpp ├── graphselect.h ├── graphwidget.cpp ├── graphwidget.h ├── grouplist.ui ├── grouplistwidget.cpp ├── grouplistwidget.h ├── heapswidget.cpp ├── heapswidget.h ├── heapswidget.ui ├── highlighter.cpp ├── highlighter.h ├── histogram.cpp ├── histogram.h ├── histogram.ui ├── histogramview.cpp ├── histogramview.h ├── histogramwidget.cpp ├── histogramwidget.h ├── hotspot.ui ├── hotspots.cpp ├── hotspots.h ├── inject.cpp ├── inject.h ├── inject.ui ├── loader ├── binloader.cpp ├── binloader.h ├── binloaderlogs.cpp ├── capture.cpp ├── capture.h ├── mtunerlib.cpp ├── mtunerlib.h └── util.h ├── moduleswidget.cpp ├── moduleswidget.h ├── moduleswidget.ui ├── mtuner.cpp ├── mtuner.h ├── mtuner.qph ├── mtuner.qrc ├── mtuner.rc ├── mtuner.ui ├── mtuner_de.qm ├── mtuner_de.ts ├── mtuner_en.qm ├── mtuner_en.ts ├── mtuner_it.qm ├── mtuner_it.ts ├── mtuner_rs.qm ├── mtuner_rs.ts ├── mtunerlang.bat ├── mtunerlang.pro ├── mtunermain.cpp ├── operationsearch.cpp ├── operationsearch.h ├── operationsearch.ui ├── operationslist.cpp ├── operationslist.h ├── operationslist.ui ├── progressbar.ui ├── projectsmanager.cpp ├── projectsmanager.h ├── projectsmanager.ui ├── sourceview.cpp ├── sourceview.h ├── stackandsource.cpp ├── stackandsource.h ├── stackandsource.ui ├── stacktrace.cpp ├── stacktrace.h ├── stacktrace.ui ├── stacktree.ui ├── stacktreewidget.cpp ├── stacktreewidget.h ├── startpage.cpp ├── startpage.h ├── startpage.ui ├── stats.cpp ├── stats.h ├── stats.ui ├── symbolstore.cpp ├── symbolstore.h ├── symbolstore.ui ├── tagtree.ui ├── tagtreewidget.cpp ├── tagtreewidget.h ├── treemap.cpp ├── treemap.h ├── treemap.ui ├── treemapview.cpp ├── treemapview.h ├── version.h ├── welcome.cpp ├── welcome.h └── welcome.ui /.appveyor.yml: -------------------------------------------------------------------------------- 1 | 2 | environment: 3 | matrix: 4 | 5 | - job_name: Windows 6 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 7 | configuration: Debug 8 | platform: x64 9 | 10 | - job_name: Windows 11 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 12 | configuration: Release 13 | platform: x64 14 | 15 | - job_name: Windows 16 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 17 | configuration: Retail 18 | platform: x64 19 | 20 | - job_name: Linux 21 | APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu2204 22 | buildcfg: debug64 23 | 24 | - job_name: Linux 25 | APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu2204 26 | buildcfg: release64 27 | 28 | - job_name: Linux 29 | APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu2204 30 | buildcfg: retail64 31 | 32 | - job_name: OSX 33 | APPVEYOR_BUILD_WORKER_IMAGE: macOS-sonoma 34 | buildcfg: debug64 35 | 36 | - job_name: OSX 37 | APPVEYOR_BUILD_WORKER_IMAGE: macOS-sonoma 38 | buildcfg: release64 39 | 40 | - job_name: OSX 41 | APPVEYOR_BUILD_WORKER_IMAGE: macOS-sonoma 42 | buildcfg: retail64 43 | 44 | shallow_clone: true 45 | 46 | install: 47 | - git submodule init 48 | - git submodule update 49 | 50 | for: 51 | 52 | # ====================================== 53 | # Windows 54 | # ====================================== 55 | 56 | - 57 | matrix: 58 | only: 59 | - job_name: Windows 60 | - QTDIR: C:\Qt\6.5.3\msvc2019_64 61 | 62 | init: 63 | - set QTDIR=C:\Qt\6.5.3\msvc2019_64 64 | - git clone --depth 1 https://github.com/rjpcomputing/luaforwindows luaforwindows 65 | - copy %cd%\luaforwindows\files\lua5.1.exe %cd%\luaforwindows\files\lua.exe 66 | - set PATH=%cd%\luaforwindows\files;C:\Qt\6.5.3\msvc2019_64\bin;%PATH% 67 | - git clone --recursive --depth 1 https://github.com/milostosic/MTuner MTuner 68 | 69 | install: 70 | - MTuner\build\tools\bin\windows\genie.exe --file=MTuner\src\MTuner\genie\genie.lua vs2022 71 | 72 | build: ../.build/windows/vs2022/MTuner/projects/MTuner.sln 73 | 74 | # ====================================== 75 | # Linux 76 | # ====================================== 77 | 78 | - 79 | matrix: 80 | only: 81 | - job_name: Linux 82 | 83 | init: 84 | - sudo apt install -y lua5.3 lua-filesystem 85 | - export QTDIR="$HOME/Qt/6.5.3/gcc_64" 86 | - export PATH="$HOME/Qt/6.5.3/gcc_64/bin:$HOME/Qt/6.5.3/gcc_64/libexec:/home/appveyor/Qt/6.5.3/gcc_64/libexec:$PATH" 87 | - export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$HOME/Qt/6.5.3/gcc_64/lib/pkgconfig" 88 | - git clone --recursive --depth 1 https://github.com/milostosic/MTuner MTuner 89 | - git clone --depth 1 https://github.com/bkaradzic/GENie GENie 90 | - cd GENie && make && cd .. 91 | 92 | install: 93 | - ./GENie/bin/linux/genie --file=MTuner/src/MTuner/genie/genie.lua --gcc=linux-gcc gmake 94 | 95 | build_script: 96 | - cd MTuner/.build/linux/linux-gcc/MTuner/projects/ 97 | - make config=${buildcfg} 98 | 99 | # ====================================== 100 | # OSX 101 | # ====================================== 102 | 103 | - 104 | matrix: 105 | only: 106 | - job_name: OSX 107 | 108 | init: 109 | - export QTDIR="$HOME/Qt/6.5.3/macos/" 110 | - export PATH="$HOME/Qt/6.5.3/macos/bin:$HOME/Qt/6.5.3/macos/libexec:$PATH" 111 | - export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$HOME/Qt/6.5.3/macos/lib/pkgconfig" 112 | - curl -L -R -O https://www.lua.org/ftp/lua-5.4.7.tar.gz 113 | - tar zxf lua-5.4.7.tar.gz 114 | - cd lua-5.4.7 && sudo make all test && sudo make install && cd .. 115 | - git clone --recursive --depth 1 https://github.com/milostosic/MTuner MTuner 116 | - git clone --depth 1 https://github.com/bkaradzic/GENie GENie # build GENie from source: we don't know the target CPU, can't use ARM binary from 'build' 117 | - cd GENie && make && cd .. 118 | 119 | install: 120 | - ./GENie/bin/darwin/genie --file=MTuner/src/MTuner/genie/genie.lua --gcc=osx-x64 gmake 121 | 122 | build_script: 123 | - cd MTuner/.build/osx/clang/MTuner/projects/ 124 | - make config=${buildcfg} 125 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = tab 5 | indent_size = 4 6 | end_of_line = lf 7 | max_line_length = 150 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | max_line_length = 80 14 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.c eol=lf 2 | *.cpp eol=lf 3 | *.h eol=lf 4 | *.hpp eol=lf 5 | *.hlsl eol=lf 6 | *.md eol=lf 7 | *.lua eol=lf 8 | *.mk eol=lf 9 | makefile eol=lf 10 | 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .qt 2 | .build 3 | .DS_Store 4 | 5 | 6 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "build"] 2 | path = build 3 | url = https://github.com/RudjiGames/build.git 4 | [submodule "src/libs/rbase"] 5 | path = src/libs/rbase 6 | url = https://github.com/RudjiGames/rbase.git 7 | [submodule "src/libs/rmem"] 8 | path = src/libs/rmem 9 | url = https://github.com/RudjiGames/rmem.git 10 | [submodule "src/libs/rqt"] 11 | path = src/libs/rqt 12 | url = https://github.com/RudjiGames/rqt.git 13 | [submodule "src/tools/cmdline/MTunerCmd"] 14 | path = src/tools/cmdline/MTunerCmd 15 | url = https://github.com/RudjiGames/MTunerCmd.git 16 | [submodule "src/tools/cmdline/MTunerInject"] 17 | path = src/tools/cmdline/MTunerInject 18 | url = https://github.com/RudjiGames/MTunerInject.git 19 | [submodule "src/tools/cmdline/MTunerDLL"] 20 | path = src/tools/cmdline/MTunerDLL 21 | url = https://github.com/RudjiGames/MTunerDLL.git 22 | [submodule "src/libs/rdebug"] 23 | path = src/libs/rdebug 24 | url = https://github.com/RudjiGames/rdebug.git 25 | [submodule "3rd/DIA"] 26 | path = 3rd/DIA 27 | url = https://github.com/RudjiGames/DIA.git 28 | [submodule "3rd/unordered_dense"] 29 | path = 3rd/unordered_dense 30 | url = https://github.com/martinus/unordered_dense.git 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright 2023 Milos Tosic 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![MTuner logo](img/mtuner.png) 2 | 3 | [![Build status](https://ci.appveyor.com/api/projects/status/8ops3q96bhvpoy4t?svg=true)](https://ci.appveyor.com/project/milostosic/mtuner) 4 | [![License](https://img.shields.io/badge/license-BSD--2%20clause-blue.svg)](https://github.com/RudjiGames/MTuner/blob/master/LICENSE) 5 | 6 | **MTuner** is a C/C++ memory profiler and memory leak finder for Windows, PlayStation 3/4/5, Nintendo Switch, Android and other platforms. 7 | 8 | **MTuner** utilizes a novel approach to memory profiling and analysis, keeping entire time-based history of memory operations. This gives an unique insight in memory related behavior of your software by making queries over the entire data set. 9 | 10 | While **MTuner** was created for profiling C/C++ applications, it is possible to profile memory for programs written in other languages as long as there is corresponding debug symbol information. Users can convert DMD CodeView/DWARF debug symbols to PDB format using [cv2pdb](https://github.com/rainers/cv2pdb). 11 | 12 | ![MTuner screenshot](https://github.com/RudjiGames/MTuner/blob/master/img/mtuner_screenshot.png) 13 | 14 | Source Code 15 | ====== 16 | 17 | You can get the latest source code by cloning it from github: 18 | 19 | git clone https://github.com/RudjiGames/MTuner.git 20 | 21 | After cloning, we need to download dependencies: 22 | 23 | git submodule init 24 | git submodule update 25 | 26 | Download 27 | ====== 28 | 29 | Binaries can be downloaded from [releases](https://github.com/RudjiGames/MTuner/releases) page 30 | 31 | NB: If your application crashes while being profiled with **MTuner**, you can try adding **MTuner** folder to 'Exclusions' list under 'Virus & threat protection settings' 32 | 33 | Documentation 34 | ====== 35 | 36 | **MTuner** documentation can be found [here](https://RudjiGames.github.io/MTuner/). 37 | 38 | Build 39 | ====== 40 | 41 | **MTuner** uses [**Qt**](https://www.qt.io/) framework for user interface so it needs to be installed on the build machine. The build system is based on [**GENie**](https://github.com/bkaradzic/GENie) and [**build**](https://github.com/RudjiGames/build) in order to dramatically simplify managing build configurations and dependencies. 42 | 43 | After cloning the repository and dependencies, here are the steps to build *MTuner*. 44 | 45 | **MinGW** 46 | 47 | $ cd MTuner/genie 48 | $ genie --gcc=mingw-gcc gmake 49 | $ cd ../../.build/windows/mingw-gcc/MTuner/projects/ 50 | $ make 51 | MINGW environment variable must be set and point to the MinGW installation directory. 52 | Tested with [TDM64 MinGW](http://tdm-gcc.tdragon.net/download) using [OpenMP package](http://sourceforge.net/projects/tdm-gcc/files/TDM-GCC%205%20series/5.1.0-tdm64-1/gcc-5.1.0-tdm64-1-openmp.zip/download) 53 | 54 | **Visual Studio** 55 | 56 | > cd MTuner/genie 57 | > genie vs2022 58 | Solution will be located here: *{Clone root}/.build/windows/vs2022/projects/MTuner/MTuner.sln* 59 | 60 | NB: building [**Qt**](https://www.qt.io/) based projects with [**build**](https://github.com/RudjiGames/build) requires Lua to be installed. 61 | 62 | Environment variables are used to locate [**Qt**](https://www.qt.io/) installation, example: 63 | 64 | set QTDIR_VS2022_x86=C:\\Qt\6.3.1\msvc2019_64 * 65 | set QTDIR_VS2022_x64=C:\\Qt\6.3.1\msvc2019_64 66 | 67 | *\* Note that [**Qt**](https://www.qt.io/) deprecated 32bit builds which is why both variables point to same location.* 68 | 69 | License (BSD 2-clause) 70 | ====== 71 | 72 | 73 | 74 | 75 | 76 | Copyright 2023 Milos Tosic. All rights reserved. 77 | 78 | https://github.com/RudjiGames/MTuner 79 | 80 | Redistribution and use in source and binary forms, with or without 81 | modification, are permitted provided that the following conditions are met: 82 | 83 | 1. Redistributions of source code must retain the above copyright notice, 84 | this list of conditions and the following disclaimer. 85 | 86 | 2. Redistributions in binary form must reproduce the above copyright 87 | notice, this list of conditions and the following disclaimer in the 88 | documentation and/or other materials provided with the distribution. 89 | 90 | THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS OR 91 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 92 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 93 | EVENT SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 94 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 95 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 96 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 97 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 98 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 99 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 100 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-modernist -------------------------------------------------------------------------------- /img/mtuner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/img/mtuner.png -------------------------------------------------------------------------------- /img/mtuner_screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/img/mtuner_screenshot.png -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2023 Milos Toisc. All rights reserved. 3 | # License: http://www.opensource.org/licenses/BSD-2-Clause 4 | # 5 | 6 | GENIE=../build/tools/bin/$(OS)/genie 7 | 8 | all: 9 | $(GENIE) vs2015 10 | $(GENIE) vs2017 11 | $(GENIE) --gcc=android-arm gmake 12 | $(GENIE) --gcc=android-mips gmake 13 | $(GENIE) --gcc=android-x86 gmake 14 | $(GENIE) --gcc=mingw-gcc gmake 15 | $(GENIE) --gcc=linux-gcc gmake 16 | $(GENIE) --gcc=osx gmake 17 | $(GENIE) --gcc=ios-arm gmake 18 | $(GENIE) --gcc=ios-simulator gmake 19 | $(GENIE) --gcc=ios-simulator64 gmake 20 | $(GENIE) xcode4 21 | 22 | gmake-linux: 23 | $(GENIE) --file=genie/genie.lua --gcc=linux-gcc gmake 24 | #linux-debug32: gmake-linux 25 | # make -R -C ../.build/linux/gcc/MTuner/projects config=debug32 26 | #linux-release32: gmake-linux 27 | # make -R -C ../.build/linux/gcc/MTuner/projects config=release32 28 | linux-debug64: gmake-linux 29 | make -R -C ../.build/linux/gcc/MTuner/projects config=debug64 30 | linux-release64: gmake-linux 31 | make -R -C ../.build/linux/gcc/MTuner/projects config=release64 32 | linux: linux-debug64 linux-release64 33 | 34 | gmake-mingw-gcc: 35 | $(GENIE) --file=genie/genie.lua --gcc=mingw-gcc gmake 36 | #mingw-gcc-debug32: gmake-mingw-gcc 37 | # make -R -C ../.build/windows/mingw-gcc/MTuner/projects config=debug32 38 | #mingw-gcc-release32: gmake-mingw-gcc 39 | # make -R -C ../.build/windows/mingw-gcc/MTuner/projects config=release32 40 | mingw-gcc-debug64: gmake-mingw-gcc 41 | make -R -C ../.build/windows/mingw-gcc/MTuner/projects config=debug64 42 | mingw-gcc-release64: gmake-mingw-gcc 43 | make -R -C ../.build/windows/mingw-gcc/MTuner/projects config=release64 44 | mingw-gcc: mingw-gcc-debug64 mingw-gcc-release64 45 | 46 | gmake-mingw-clang: 47 | $(GENIE) --file=genie/genie.lua --clang=mingw-clang gmake 48 | #mingw-clang-debug32: gmake-mingw-clang 49 | # make -R -C ../.build/windows/mingw-clang/MTuner/projects config=debug32 50 | #mingw-clang-release32: gmake-mingw-clang 51 | # make -R -C ../.build/windows/mingw-clang/MTuner/projects config=release32 52 | mingw-clang-debug64: gmake-mingw-clang 53 | make -R -C ../.build/windows/mingw-clang/MTuner/projects config=debug64 54 | mingw-clang-release64: gmake-mingw-clang 55 | make -R -C ../.build/windows/mingw-clang/MTuner/projects config=release64 56 | mingw-clang: mingw-clang-debug64 mingw-clang-release64 57 | 58 | vs2015: 59 | $(GENIE) --file=genie/genie.lua vs2015 60 | 61 | vs2017: 62 | $(GENIE) --file=genie/genie.lua vs2017 63 | 64 | ../.build/osx/gcc/MTuner/projects: 65 | $(GENIE) --file=genie/genie.lua --gcc=osx gmake 66 | osx-debug64: ../.build/osx/gcc/MTuner/projects 67 | make -C ../.build/osx/gcc/MTuner/projects config=debug64 68 | osx-release64: ../.build/osx/gcc/MTuner/projects 69 | make -C ../.build/osx/gcc/MTuner/projects config=release64 70 | osx: osx-debug64 osx-release64 71 | 72 | clean: 73 | @echo Cleaning... 74 | -@rm -rf ../.build 75 | 76 | ### 77 | 78 | SILENT ?= @ 79 | 80 | UNAME := $(shell uname) 81 | ifeq ($(UNAME),$(filter $(UNAME),Linux GNU Darwin)) 82 | ifeq ($(UNAME),$(filter $(UNAME),Darwin)) 83 | OS=darwin 84 | else 85 | OS=linux 86 | endif 87 | else 88 | OS=windows 89 | endif 90 | 91 | -------------------------------------------------------------------------------- /scripts/MTunerBuildSDKSony.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set PLATFORM=orbis 4 | IF "%1"=="orbis" set PLATFORM=orbis 5 | IF "%1"=="prospero" set PLATFORM=prospero 6 | IF "%1"=="ps4" set PLATFORM=orbis 7 | IF "%1"=="ps5" set PLATFORM=prospero 8 | 9 | set PLATFORM_SHORT=ps4 10 | IF "%1"=="orbis" set PLATFORM_SHORT=ps4 11 | IF "%1"=="prospero" set PLATFORM_SHORT=ps5 12 | IF "%1"=="ps4" set PLATFORM_SHORT=ps4 13 | IF "%1"=="ps5" set PLATFORM_SHORT=ps5 14 | 15 | echo Generating makefiles for %PLATFORM_SHORT% 16 | ..\build\tools\bin\windows\genie.exe --file=..\src\libs\rmem\genie\genie.lua --gcc=%PLATFORM% gmake 17 | cd ..\.build\%PLATFORM%\%PLATFORM%-clang\rmem\projects\ 18 | make -R config=debug64 rmem 19 | make -R config=release64 rmem 20 | cd ..\..\..\..\..\scripts 21 | mkdir SDK\inc 22 | mkdir SDK\lib\%PLATFORM_SHORT% 23 | copy ..\src\libs\rmem\inc\*.* SDK\inc 24 | copy ..\.build\%PLATFORM%\%PLATFORM%-clang\rmem\x64\debug\lib\librmem_debug.a SDK\lib\%PLATFORM_SHORT%\librmem_debug.a 25 | copy ..\.build\%PLATFORM%\%PLATFORM%-clang\rmem\x64\release\lib\librmem_release.a SDK\lib\%PLATFORM_SHORT%\librmem_release.a 26 | 27 | -------------------------------------------------------------------------------- /scripts/MTunerGenerateOSX.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | target="$1" 3 | 4 | if [ -z "$target" ]; then 5 | action="--gcc=osx-x64 gmake" 6 | fi 7 | 8 | cd ../src/MTuner/genie 9 | ../../../build/tools/bin/darwin/genie $action 10 | cd ../../../srcipts 11 | 12 | -------------------------------------------------------------------------------- /scripts/MTunerGenerateVS2022sln.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | echo Generating solution and project files for Visual Studio 2022 3 | ..\build\tools\bin\windows\genie.exe --file=..\src\MTuner\genie\genie.lua vs2022 4 | -------------------------------------------------------------------------------- /src/MTuner/genie/MTuner.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- Copyright 2025 Milos Tosic. All rights reserved. 3 | -- License: http://www.opensource.org/licenses/BSD-2-Clause 4 | -- 5 | 6 | function projectDependencies_MTuner() 7 | return { "rmem", "rdebug", "rqt" } 8 | end 9 | 10 | function projectExtraConfig_MTuner() 11 | configuration { "*-gcc*" } 12 | buildoptions { 13 | "-fopenmp", 14 | } 15 | configuration { "osx" } 16 | defines { "QT_STRINGVIEW_LEVEL=2" } 17 | configuration {} 18 | defines { "_SILENCE_ALL_MS_EXT_DEPRECATION_WARNINGS" } 19 | end 20 | 21 | function projectExtraConfigExecutable_MTuner() 22 | if getTargetOS() == "linux" then 23 | links { 24 | "gomp", 25 | } 26 | end 27 | 28 | configuration {} 29 | end 30 | 31 | function projectAdd_MTuner() 32 | addProject_qt("MTuner") 33 | end 34 | 35 | -------------------------------------------------------------------------------- /src/MTuner/genie/genie.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- Copyright 2025 Milos Tosic. All rights reserved. 3 | -- License: http://www.opensource.org/licenses/BSD-2-Clause 4 | -- 5 | 6 | local cp = (function(x) return debug.getinfo(2, "S").source:sub(2):match("(.*[/\\])") end)() 7 | while os.isdir(cp) do cp = path.getabsolute(cp .. "/..") local tp = cp .. "/build/build.lua" 8 | if os.isfile(tp) then dofile (tp) break end end if RTM_ROOT_DIR == nil then 9 | print("EROR: dependency missing - build. Cannot continue.") os.exit() end 10 | 11 | solution "MTuner" 12 | setPlatforms() 13 | 14 | loadProject( "MTuner" ) 15 | loadProject( "MTunerDLL" ) 16 | loadProject( "MTunerCmd" ) 17 | loadProject( "MTunerInject" ) 18 | 19 | startproject "MTuner" 20 | -------------------------------------------------------------------------------- /src/MTuner/resources/fonts/Maven Pro Bold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/fonts/Maven Pro Bold.otf -------------------------------------------------------------------------------- /src/MTuner/resources/fonts/Maven Pro Medium.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/fonts/Maven Pro Medium.otf -------------------------------------------------------------------------------- /src/MTuner/resources/fonts/Maven Pro Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/fonts/Maven Pro Regular.otf -------------------------------------------------------------------------------- /src/MTuner/resources/icon256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/icon256.png -------------------------------------------------------------------------------- /src/MTuner/resources/icons/Icon256.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/icons/Icon256.ico -------------------------------------------------------------------------------- /src/MTuner/resources/icons/Icon64.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/icons/Icon64.ico -------------------------------------------------------------------------------- /src/MTuner/resources/icons/favicon_16x16.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/icons/favicon_16x16.ico -------------------------------------------------------------------------------- /src/MTuner/resources/icons/favicon_32x32.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/icons/favicon_32x32.ico -------------------------------------------------------------------------------- /src/MTuner/resources/images/Documentation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/Documentation.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/Editor64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/Editor64.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/Filter64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/Filter64.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/Flame64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/Flame64.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/FlameSelected64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/FlameSelected64.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/Graph128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/Graph128.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/Graph256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/Graph256.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/Graph64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/Graph64.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/Graph64_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/Graph64_hover.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/Group64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/Group64.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/GroupSelected64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/GroupSelected64.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/Heaps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/Heaps.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/Histogram64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/Histogram64.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/Icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/Icon128.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/Icon256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/Icon256.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/Icon64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/Icon64.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/Leak64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/Leak64.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/LeakSelected64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/LeakSelected64.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/List64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/List64.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/ListSelected64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/ListSelected64.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/Lupa16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/Lupa16.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/Open64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/Open64.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/Projects64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/Projects64.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/Run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/Run.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/StackTraceSource64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/StackTraceSource64.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/StackTree64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/StackTree64.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/StackTreeSelected64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/StackTreeSelected64.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/Symbol64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/Symbol64.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/TreeMap64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/TreeMap64.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/TreeMapSelected64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/TreeMapSelected64.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/dock_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/dock_close.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/dock_close_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/dock_close_hover.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/dock_detach.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/dock_detach.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/dock_detach_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/dock_detach_hover.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/gnu64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/gnu64.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/link64_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/link64_active.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/link64_inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/link64_inactive.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/linkedin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/linkedin.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/logo.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/modules128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/modules128.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/modules64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/modules64.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/notok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/notok.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/ok.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/red_dot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/red_dot.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/table.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/toolchain_android_arm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/toolchain_android_arm.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/toolchain_android_mips.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/toolchain_android_mips.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/toolchain_android_x86.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/toolchain_android_x86.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/toolchain_mingw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/toolchain_mingw.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/toolchain_ps3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/toolchain_ps3.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/toolchain_ps4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/toolchain_ps4.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/toolchain_ps5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/toolchain_ps5.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/toolchain_switch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/toolchain_switch.png -------------------------------------------------------------------------------- /src/MTuner/resources/images/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/resources/images/twitter.png -------------------------------------------------------------------------------- /src/MTuner/src/MTuner_pch.cpp: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #include 7 | 8 | #define RTM_LIBHANDLER_DEFINE 9 | #include 10 | 11 | namespace mtuner { 12 | 13 | bool init(rtmLibInterface* _libInterface) 14 | { 15 | g_allocator = _libInterface ? _libInterface->m_memory : 0; 16 | g_errorHandler = _libInterface ? _libInterface->m_error : 0; 17 | return true; 18 | } 19 | 20 | void shutDown() 21 | { 22 | } 23 | 24 | } // namespace mtuner 25 | -------------------------------------------------------------------------------- /src/MTuner/src/MTuner_pch.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_PCH_H 7 | #define RTM_MTUNER_PCH_H 8 | 9 | #define RBASE_NAMESPACE mtuner 10 | #define RTM_DEFINE_STL_TYPES 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include 58 | #include 59 | #include 60 | #include 61 | #include 62 | #include 63 | 64 | #include 65 | #include 66 | #include 67 | #include 68 | #include 69 | #include 70 | #include 71 | #include 72 | #include 73 | #include 74 | #include 75 | #include 76 | #include 77 | #include 78 | #include 79 | #include 80 | #include 81 | #include 82 | #include 83 | #include 84 | 85 | #include "../3rd/unordered_dense/include/ankerl/unordered_dense.h" 86 | 87 | #endif // RTM_MTUNER_PCH_H 88 | -------------------------------------------------------------------------------- /src/MTuner/src/about.cpp: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | AboutDialog::AboutDialog(QWidget* _parent, Qt::WindowFlags /*_flags*/) : 11 | QDialog(_parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint) 12 | { 13 | ui.setupUi(this); 14 | QLabel* version = findChild("labelVersion"); 15 | version->setText(tr("Version") + QString(" ") + QString(MTunerVersion)); 16 | } 17 | 18 | void AboutDialog::changeEvent(QEvent* _event) 19 | { 20 | QDialog::changeEvent(_event); 21 | if (_event->type() == QEvent::LanguageChange) 22 | ui.retranslateUi(this); 23 | } 24 | -------------------------------------------------------------------------------- /src/MTuner/src/about.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_ABOUT_H 7 | #define RTM_MTUNER_ABOUT_H 8 | 9 | #include 10 | 11 | class AboutDialog : public QDialog 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | AboutDialog(QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 17 | void changeEvent(QEvent* _event); 18 | 19 | private: 20 | Ui::About ui; 21 | }; 22 | 23 | #endif // RTM_MTUNER_ABOUT_H 24 | -------------------------------------------------------------------------------- /src/MTuner/src/bigtable.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_BIGTABLE_H 7 | #define RTM_MTUNER_BIGTABLE_H 8 | 9 | #include 10 | 11 | class BigTableTableWidget; 12 | 13 | class BigTableSource 14 | { 15 | public: 16 | virtual QStringList getHeaderInfo(int32_t& _sortCol, Qt::SortOrder& _sortOrder, QList& _widths) = 0; 17 | virtual uint32_t getNumberOfRows() = 0; 18 | virtual QString getItem(uint32_t _index, int32_t _column, QColor* _color, bool* _setColor) = 0; 19 | virtual void getItem(uint32_t _index, void**) = 0; 20 | virtual Qt::AlignmentFlag getAlignment(uint32_t _index) = 0; 21 | virtual uint32_t getItemIndex(void* _item) = 0; 22 | virtual void sortColumn(uint32_t _colIndex, Qt::SortOrder _order) = 0; 23 | }; 24 | 25 | class BigTable : public QWidget 26 | { 27 | Q_OBJECT 28 | 29 | private: 30 | QStringList m_header; 31 | BigTableTableWidget* m_tree; 32 | QScrollBar* m_scroll; 33 | BigTableSource* m_source; 34 | int32_t m_numColumns; 35 | int32_t m_selectedRows; 36 | int32_t m_firstVisible; 37 | int32_t m_visibleRows; 38 | 39 | public: 40 | BigTable(QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 41 | 42 | void changeEvent(QEvent* _event); 43 | void setSource(BigTableSource* _src); 44 | void select(void* _item); 45 | void updateTable(); 46 | void resetView(); 47 | void ensureSelectionVisible(); 48 | 49 | /// QWidget 50 | void resizeEvent(QResizeEvent* _event); 51 | void wheelEvent(QWheelEvent* _event); 52 | void keyPressEvent(QKeyEvent* _event); 53 | 54 | QHeaderView* getHeader() { return m_tree->horizontalHeader(); } 55 | 56 | Q_SIGNALS: 57 | void itemSelected(void*); 58 | void itemRightClicked(void*, const QPoint&); 59 | 60 | public Q_SLOTS: 61 | void scroll(int); 62 | void rowSelected(QTableWidgetItem*); 63 | void rowRightClick(QTableWidgetItem*, const QPoint&); 64 | void sortSelection(int, Qt::SortOrder); 65 | 66 | private: 67 | Ui::BigTableWidget ui; 68 | }; 69 | 70 | #endif // RTM_MTUNER_BIGTABLE_H 71 | -------------------------------------------------------------------------------- /src/MTuner/src/bigtable.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | BigTableWidget 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 300 11 | 12 | 13 | 14 | Qt::StrongFocus 15 | 16 | 17 | BigTable 18 | 19 | 20 | 21 | 0 22 | 23 | 24 | 0 25 | 26 | 27 | 0 28 | 29 | 30 | 0 31 | 32 | 33 | 0 34 | 35 | 36 | 37 | 38 | Qt::ScrollBarAlwaysOff 39 | 40 | 41 | QAbstractItemView::NoEditTriggers 42 | 43 | 44 | false 45 | 46 | 47 | QAbstractItemView::SingleSelection 48 | 49 | 50 | QAbstractItemView::SelectRows 51 | 52 | 53 | QAbstractItemView::ScrollPerPixel 54 | 55 | 56 | false 57 | 58 | 59 | false 60 | 61 | 62 | 63 | 64 | 65 | 66 | Qt::Vertical 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | BigTableTableWidget 75 | QTableWidget 76 |
../src/bigtabletablewidget.h
77 |
78 |
79 | 80 | 81 |
82 | -------------------------------------------------------------------------------- /src/MTuner/src/bigtabletablewidget.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_BIGTABLETABLEWIDGET_H 7 | #define RTM_MTUNER_BIGTABLETABLEWIDGET_H 8 | 9 | class BigTableTableWidget : public QTableWidget 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | BigTableTableWidget(QWidget* _parent = 0); 15 | 16 | /// Disable default navigation 17 | QModelIndex moveCursor(QAbstractItemView::CursorAction, Qt::KeyboardModifiers) { return QModelIndex(); } 18 | void contextMenuEvent(QContextMenuEvent* _event); 19 | 20 | Q_SIGNALS: 21 | void itemContextMenu(QTableWidgetItem*, const QPoint&); 22 | }; 23 | 24 | #endif // RTM_MTUNER_BIGTABLETABLEWIDGET_H 25 | -------------------------------------------------------------------------------- /src/MTuner/src/binloaderview.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_BINLOADERVIEW_H 7 | #define RTM_MTUNER_BINLOADERVIEW_H 8 | 9 | #include 10 | #include 11 | 12 | class Hotspots; 13 | class OperationsList; 14 | class HotspotsWidget; 15 | class StackTreeWidget; 16 | struct CaptureContext; 17 | 18 | class BinLoaderView : public QWidget 19 | { 20 | Q_OBJECT 21 | 22 | private: 23 | QTabWidget* m_tab; 24 | TreeMapWidget* m_treeMap; 25 | CaptureContext* m_context; 26 | OperationsList* m_operationList; 27 | GroupList* m_groupList; 28 | HotspotsWidget* m_hotspots; 29 | StackTreeWidget* m_stackTree; 30 | OperationsList* m_operationListInvalid; 31 | uint64_t m_minTime; 32 | uint64_t m_maxTime; 33 | uint64_t m_currentHeap; 34 | rdebug::ModuleInfo* m_currentModule; 35 | rtm::StackTrace** m_savedStackTraces; 36 | uint32_t m_savedStackTracesCount; 37 | int m_histogramType; 38 | int m_histogramMode; 39 | bool m_histogramPeaks; 40 | bool m_histogramScale; 41 | bool m_filteringEnabled; 42 | 43 | public: 44 | BinLoaderView(QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 45 | virtual ~BinLoaderView(); 46 | 47 | CaptureContext* getContext() { return m_context; } 48 | void setContext(CaptureContext* _context); 49 | 50 | rtm::StackTrace** getSavedStackTraces() { return m_savedStackTraces; } 51 | uint32_t getSavedStackTracesCount() { return m_savedStackTracesCount; } 52 | 53 | void changeEvent(QEvent* _event); 54 | void setHistogramType(int _type) { m_histogramType = _type; } 55 | void setHistogramMode(int _mode) { m_histogramMode = _mode; } 56 | void setHistogramPeaks(bool _peaks) { m_histogramPeaks = _peaks; } 57 | void setHistogramScale(bool _scale) { m_histogramPeaks = _scale; } 58 | int getHistogramType() const { return m_histogramType; } 59 | int getHistogramMode() const { return m_histogramMode; } 60 | bool getHistogramPeaks() const { return m_histogramPeaks; } 61 | bool getHistogramScale() const { return m_histogramScale; } 62 | uint64_t getMinTime() { return m_minTime; } 63 | uint64_t getMaxTime() { return m_maxTime; } 64 | void setMinTime(uint64_t _minTime) { m_minTime = _minTime; } 65 | void setMaxTime(uint64_t _maxTime) { m_maxTime = _maxTime; } 66 | uint64_t getCurrentHeap() { return m_currentHeap; } 67 | void setCurrentHeap(uint64_t inHeap) { m_currentHeap = inHeap; } 68 | rdebug::ModuleInfo* getCurrentModule() { return m_currentModule; } 69 | void setCurrentModule(rdebug::ModuleInfo* _module) { m_currentModule = _module; } 70 | void setFilteringEnabled(bool _filter); 71 | bool getFilteringEnabled() const { return m_filteringEnabled; } 72 | 73 | void readSettings(); 74 | void saveSettings(); 75 | 76 | public Q_SLOTS: 77 | void saveStackTrace(rtm::StackTrace**, int); 78 | 79 | Q_SIGNALS: 80 | void setStackTrace(rtm::StackTrace**, int); 81 | void highlightTime(uint64_t); 82 | void highlightRange(uint64_t, uint64_t); 83 | void selectRange(uint64_t, uint64_t); 84 | 85 | private: 86 | Ui::BinLoaderView ui; 87 | }; 88 | 89 | #endif // RTM_MTUNER_BINLOADERVIEW_H 90 | -------------------------------------------------------------------------------- /src/MTuner/src/capturecontext.cpp: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | CaptureContext::CaptureContext() 12 | { 13 | m_symbolResolver = 0; 14 | m_capture = new rtm::Capture(); 15 | m_toolchain = rmem::ToolChain::Unknown; 16 | m_binLoaderView = 0; 17 | } 18 | 19 | CaptureContext::~CaptureContext() 20 | { 21 | if (m_symbolResolver) 22 | { 23 | rdebug::symbolResolverDelete((uintptr_t)m_symbolResolver); 24 | m_symbolResolver = 0; 25 | } 26 | } 27 | 28 | void CaptureContext::setupResolver(rdebug::Toolchain& _tc, std::string& _executable, rdebug::module_load_cb _callback, void* _data) 29 | { 30 | switch (_tc.m_type) 31 | { 32 | case rdebug::Toolchain::MSVC: 33 | { 34 | std::string symbolStorePath = _tc.m_toolchainPath; 35 | size_t len = symbolStorePath.length(); 36 | if (len) 37 | while (--len) 38 | { 39 | if (symbolStorePath.c_str()[len] == L'\\') break; 40 | if (symbolStorePath.c_str()[len] == L'/') break; 41 | } 42 | 43 | if (len) 44 | { 45 | char buffer[2048]; 46 | strcpy(buffer, symbolStorePath.c_str()); 47 | buffer[len+1] = L'\0'; 48 | m_symbolStoreDName = buffer; 49 | } 50 | else 51 | { 52 | m_symbolStoreDName = ""; 53 | } 54 | } 55 | break; 56 | case rdebug::Toolchain::GCC: 57 | case rdebug::Toolchain::PS3SNC: 58 | case rdebug::Toolchain::PS4: 59 | case rdebug::Toolchain::PS5: 60 | case rdebug::Toolchain::Unknown: 61 | break; 62 | }; 63 | 64 | m_symbolResolver = rdebug::symbolResolverCreate(m_capture->getModuleInfos().data(), (uint32_t)m_capture->getModuleInfos().size(), _executable.c_str(), _callback, _data); 65 | } 66 | 67 | void CaptureContext::resolveStackFrame(uint64_t _address, rdebug::StackFrame& _frame) 68 | { 69 | if (m_symbolResolver) 70 | rdebug::symbolResolverGetFrame(m_symbolResolver, _address, &_frame); 71 | } 72 | -------------------------------------------------------------------------------- /src/MTuner/src/capturecontext.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_CAPTURE_CONTEXT_H 7 | #define RTM_MTUNER_CAPTURE_CONTEXT_H 8 | 9 | #include 10 | 11 | class BinLoaderView; 12 | 13 | struct CaptureContext 14 | { 15 | rtm::Capture* m_capture; 16 | uintptr_t m_symbolResolver; 17 | std::string m_symbolStoreDName; 18 | rmem::ToolChain::Enum m_toolchain; 19 | BinLoaderView* m_binLoaderView; 20 | 21 | CaptureContext(); 22 | ~CaptureContext(); 23 | 24 | void setupResolver(rdebug::Toolchain& _tc, std::string& _executable, rdebug::module_load_cb _callback, void* _data); 25 | std::string getSymbolStoreDir() const { return m_symbolStoreDName; } 26 | void resolveStackFrame(uint64_t _address, rdebug::StackFrame& ioFrame); 27 | }; 28 | 29 | #endif // RTM_MTUNER_CAPTURE_CONTEXT_H 30 | -------------------------------------------------------------------------------- /src/MTuner/src/centralwidget.cpp: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | CentralWidget::CentralWidget(QWidget* _parent, Qt::WindowFlags _flags) : 13 | QWidget(_parent, _flags) 14 | { 15 | ui.setupUi(this); 16 | 17 | m_tabWidget = findChild("tabWidget"); 18 | m_tabWidget->addTab(new StartPageWidget(), QObject::tr("Start Page")); 19 | 20 | connect(m_tabWidget, SIGNAL(currentChanged(int)), this, SLOT(tabSelectionChanged(int))); 21 | connect(m_tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(tabClose(int))); 22 | } 23 | 24 | void CentralWidget::changeEvent(QEvent* _event) 25 | { 26 | QWidget::changeEvent(_event); 27 | switch (_event->type()) 28 | { 29 | case QEvent::LanguageChange: 30 | ui.retranslateUi(this); 31 | for (int i=0; icount(); ++i) 32 | { 33 | StartPageWidget* pg = qobject_cast(m_tabWidget->widget(i)); 34 | if (pg) 35 | { 36 | m_tabWidget->setTabText(i,QObject::tr("Start Page")); 37 | break; 38 | } 39 | } 40 | break; 41 | // This silences warnings from the compiler about unhandled cases 42 | default: 43 | break; 44 | }; 45 | } 46 | 47 | void CentralWidget::addTab(CaptureContext* _context, const QString& _name) 48 | { 49 | BinLoaderView* view = new BinLoaderView; 50 | connect(view, SIGNAL(setStackTrace(rtm::StackTrace**,int)), this, SIGNAL(setStackTrace(rtm::StackTrace**,int))); 51 | 52 | _context->m_binLoaderView = view; 53 | view->setContext(_context); 54 | m_tabWidget->addTab(view,_name); 55 | m_tabWidget->setCurrentIndex(m_tabWidget->count()-1); 56 | emit contextChanged(_context); 57 | } 58 | 59 | void CentralWidget::removeCurrentTab() 60 | { 61 | m_tabWidget->removeTab(m_tabWidget->currentIndex()); 62 | emit contextChanged(NULL); 63 | } 64 | 65 | BinLoaderView* CentralWidget::getCurrentView() 66 | { 67 | int index = m_tabWidget->currentIndex(); 68 | QWidget* widget = m_tabWidget->widget(index); 69 | BinLoaderView* view = qobject_cast(widget); 70 | return view; 71 | } 72 | 73 | void CentralWidget::toggleFilteringForCurrentView(bool _state) 74 | { 75 | BinLoaderView* view = getCurrentView(); 76 | if (view) 77 | view->setFilteringEnabled(_state); 78 | } 79 | 80 | void CentralWidget::tabSelectionChanged(int _tabIndex) 81 | { 82 | QWidget* widget = m_tabWidget->widget(_tabIndex); 83 | BinLoaderView* view = qobject_cast(widget); 84 | 85 | QString title = "MTuner"; 86 | if (view) 87 | title += " - " + m_tabWidget->tabText(_tabIndex); 88 | 89 | emit changeWindowTitle(title); 90 | emit contextChanged(view ? view->getContext() : NULL); 91 | 92 | if (view) 93 | { 94 | emit setStackTrace(view->getSavedStackTraces(), view->getSavedStackTracesCount()); 95 | emit setFilteringEnabled(view->getFilteringEnabled(),true); 96 | } 97 | else 98 | { 99 | emit setStackTrace(NULL, 0); 100 | emit setFilteringEnabled(false,false); 101 | } 102 | } 103 | 104 | void CentralWidget::tabClose(int _tabIndex) 105 | { 106 | QWidget* widget = m_tabWidget->widget(_tabIndex); 107 | m_tabWidget->removeTab(_tabIndex); 108 | delete widget; 109 | } 110 | 111 | void CentralWidget::updateFilterDataIfNeeded() 112 | { 113 | BinLoaderView* view = getCurrentView(); 114 | if (!view) 115 | return; 116 | 117 | CaptureContext* ctx = view->getContext(); 118 | if (!ctx->m_capture->getFilteringEnabled()) 119 | return; 120 | 121 | toggleFilteringForCurrentView(true); 122 | } 123 | -------------------------------------------------------------------------------- /src/MTuner/src/centralwidget.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_CENTRALWIDGET_H 7 | #define RTM_MTUNER_CENTRALWIDGET_H 8 | 9 | #include 10 | 11 | class BinLoaderView; 12 | struct CaptureContext; 13 | 14 | class CentralWidget : public QWidget 15 | { 16 | Q_OBJECT 17 | 18 | QTabWidget* m_tabWidget; 19 | 20 | public: 21 | CentralWidget(QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 22 | 23 | void changeEvent(QEvent* _event); 24 | void addTab(CaptureContext* _context, const QString& _name); 25 | void removeCurrentTab(); 26 | void toggleFilteringForCurrentView(bool _state); 27 | BinLoaderView* getCurrentView(); 28 | 29 | Q_SIGNALS: 30 | void contextChanged(CaptureContext* _view); 31 | void changeWindowTitle(const QString&); 32 | void setStackTrace(rtm::StackTrace**, int); 33 | void setFilteringEnabled(bool, bool); 34 | 35 | public Q_SLOTS: 36 | void tabSelectionChanged(int _tabIndex); 37 | void tabClose(int _index); 38 | void updateFilterDataIfNeeded(); 39 | 40 | private: 41 | Ui::CentralWidget ui; 42 | }; 43 | 44 | #endif // RTM_MTUNER_CENTRALWIDGET_H 45 | -------------------------------------------------------------------------------- /src/MTuner/src/centralwidget.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | CentralWidget 4 | 5 | 6 | 7 | 0 8 | 0 9 | 1084 10 | 732 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 0 19 | 20 | 21 | 22 | 23 | true 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/MTuner/src/env_var.cpp: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #include 7 | #include 8 | 9 | EnvVar::EnvVar(QWidget* _parent, Qt::WindowFlags _flags) 10 | : QDialog(_parent, _flags) 11 | { 12 | ui.setupUi(this); 13 | } 14 | 15 | void EnvVar::changeEvent(QEvent* _event) 16 | { 17 | QWidget::changeEvent(_event); 18 | if (_event->type() == QEvent::LanguageChange) 19 | ui.retranslateUi(this); 20 | } 21 | 22 | void EnvVar::set(const QString& _key, const QString& _val) 23 | { 24 | m_key = _key; 25 | m_val = _val; 26 | 27 | ui.key->setText(_key); 28 | ui.val->setText(_val); 29 | ui.buttonOK->setEnabled(_key.size() != 0); 30 | } 31 | 32 | void EnvVar::get(QString& _key, QString& _val) 33 | { 34 | _key = ui.key->text(); 35 | _val = ui.val->text(); 36 | } 37 | 38 | void EnvVar::keyChanged() 39 | { 40 | ui.buttonOK->setEnabled(ui.key->text().size() != 0); 41 | } 42 | 43 | void EnvVar::reject() 44 | { 45 | ui.key->setText(m_key); 46 | ui.val->setText(m_val); 47 | 48 | QDialog::reject(); 49 | } 50 | -------------------------------------------------------------------------------- /src/MTuner/src/env_var.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_ENVVAR_H 7 | #define RTM_MTUNER_ENVVAR_H 8 | 9 | #include 10 | 11 | class EnvVar : public QDialog 12 | { 13 | Q_OBJECT 14 | 15 | QString m_key; 16 | QString m_val; 17 | 18 | public: 19 | EnvVar(QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 20 | 21 | void changeEvent(QEvent* _event); 22 | void set(const QString& _key, const QString& _value); 23 | void get(QString& _key, QString& _value); 24 | 25 | public Q_SLOTS: 26 | void keyChanged(); 27 | void reject(); 28 | 29 | private: 30 | Ui::env ui; 31 | }; 32 | 33 | #endif // RTM_MTUNER_ENVVAR_H 34 | -------------------------------------------------------------------------------- /src/MTuner/src/env_var.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | env 4 | 5 | 6 | 7 | 0 8 | 0 9 | 237 10 | 71 11 | 12 | 13 | 14 | 15 | 16777215 16 | 71 17 | 18 | 19 | 20 | Environment variable 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | Variable: 31 | 32 | 33 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 34 | 35 | 36 | 37 | 38 | 39 | 40 | Value: 41 | 42 | 43 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | true 55 | 56 | 57 | 58 | 59 | 60 | 61 | true 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | Qt::Horizontal 75 | 76 | 77 | 78 | 40 79 | 20 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | OK 88 | 89 | 90 | 91 | 92 | 93 | 94 | Cancel 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | key 106 | textChanged(QString) 107 | env 108 | keyChanged() 109 | 110 | 111 | 120 112 | 16 113 | 114 | 115 | 2 116 | 45 117 | 118 | 119 | 120 | 121 | buttonOK 122 | clicked() 123 | env 124 | accept() 125 | 126 | 127 | 147 128 | 51 129 | 130 | 131 | 81 132 | 52 133 | 134 | 135 | 136 | 137 | buttonCancel 138 | clicked() 139 | env 140 | reject() 141 | 142 | 143 | 208 144 | 54 145 | 146 | 147 | 33 148 | 53 149 | 150 | 151 | 152 | 153 | buttonOK 154 | clicked() 155 | env 156 | accept() 157 | 158 | 159 | 161 160 | 57 161 | 162 | 163 | 96 164 | 58 165 | 166 | 167 | 168 | 169 | 170 | keyChanged() 171 | 172 | 173 | -------------------------------------------------------------------------------- /src/MTuner/src/environment.cpp: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | Environment::Environment(QWidget* _parent, Qt::WindowFlags _flags) 11 | : QDialog(_parent, _flags) 12 | { 13 | ui.setupUi(this); 14 | } 15 | 16 | void Environment::changeEvent(QEvent* _event) 17 | { 18 | QWidget::changeEvent(_event); 19 | if (_event->type() == QEvent::LanguageChange) 20 | ui.retranslateUi(this); 21 | } 22 | 23 | void Environment::setEnvironment(QStringList _env) 24 | { 25 | m_environment = _env; 26 | ui.tableWidget->setRowCount(_env.size()); 27 | int row = 0; 28 | Q_FOREACH(QString e, _env) 29 | { 30 | int eq = e.indexOf("="); 31 | QString variable = e.left(eq); 32 | QString value = e.right(e.size() - eq - 1); 33 | 34 | ui.tableWidget->setItem(row, 0, new QTableWidgetItem(variable)); 35 | ui.tableWidget->setItem(row, 1, new QTableWidgetItem(value)); 36 | ++row; 37 | } 38 | } 39 | 40 | QStringList Environment::getEnvironment() 41 | { 42 | QStringList ret; 43 | 44 | int numRows = ui.tableWidget->rowCount(); 45 | for (int i=0; iitem(i, 0)->text(); 48 | QString val = ui.tableWidget->item(i, 1)->text(); 49 | ret << key + QString("=") + val; 50 | } 51 | 52 | return ret; 53 | } 54 | 55 | void Environment::newVar() 56 | { 57 | EnvVar varEdit; 58 | varEdit.set("", ""); 59 | int ret = varEdit.exec(); 60 | 61 | if (ret == QDialog::Rejected) 62 | return; 63 | 64 | QString key, var; 65 | varEdit.get(key, var); 66 | 67 | int numRows = ui.tableWidget->rowCount(); 68 | ui.tableWidget->setRowCount(numRows + 1); 69 | ui.tableWidget->setItem(numRows, 0, new QTableWidgetItem(key)); 70 | ui.tableWidget->setItem(numRows, 1, new QTableWidgetItem(var)); 71 | } 72 | 73 | void Environment::editVar() 74 | { 75 | int currentRow = ui.tableWidget->currentIndex().row(); 76 | if (currentRow == -1) 77 | return; 78 | 79 | QString key = ui.tableWidget->item(currentRow, 0)->text(); 80 | QString val = ui.tableWidget->item(currentRow, 1)->text(); 81 | 82 | EnvVar varEdit; 83 | varEdit.set(key, val); 84 | int ret = varEdit.exec(); 85 | 86 | if (ret == QDialog::Rejected) 87 | return; 88 | 89 | varEdit.get(key, val); 90 | ui.tableWidget->setItem(currentRow, 0, new QTableWidgetItem(key)); 91 | ui.tableWidget->setItem(currentRow, 1, new QTableWidgetItem(val)); 92 | } 93 | 94 | void Environment::deleteVar() 95 | { 96 | int currentRow = ui.tableWidget->currentIndex().row(); 97 | if (currentRow == -1) 98 | return; 99 | 100 | ui.tableWidget->removeRow(currentRow); 101 | } 102 | 103 | void Environment::accept() 104 | { 105 | m_environment = getEnvironment(); 106 | QDialog::accept(); 107 | } 108 | 109 | void Environment::reject() 110 | { 111 | setEnvironment(m_environment); 112 | QDialog::reject(); 113 | } 114 | -------------------------------------------------------------------------------- /src/MTuner/src/environment.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_ENVIRONMENT_H 7 | #define RTM_MTUNER_ENVIRONMENT_H 8 | 9 | #include 10 | 11 | class Environment : public QDialog 12 | { 13 | Q_OBJECT 14 | 15 | QStringList m_environment; 16 | 17 | public: 18 | Environment(QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 19 | 20 | void changeEvent(QEvent* _event); 21 | 22 | void setEnvironment(QStringList _env); 23 | QStringList getEnvironment(); 24 | 25 | public Q_SLOTS: 26 | void newVar(); 27 | void editVar(); 28 | void deleteVar(); 29 | void accept(); 30 | void reject(); 31 | 32 | private: 33 | Ui::Environment ui; 34 | }; 35 | 36 | #endif // RTM_MTUNER_ENVIRONMENT_H 37 | -------------------------------------------------------------------------------- /src/MTuner/src/external_editor.cpp: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #include 7 | #include 8 | 9 | ExternalEditor::ExternalEditor(QWidget* _parent, Qt::WindowFlags _flags) : 10 | QDialog(_parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint) 11 | { 12 | RTM_UNUSED(_flags); 13 | ui.setupUi(this); 14 | m_editorText = findChild("lineEditEditor"); 15 | m_editorArgs = findChild("lineEditCmdLine"); 16 | } 17 | 18 | void ExternalEditor::changeEvent(QEvent* _event) 19 | { 20 | QDialog::changeEvent(_event); 21 | if (_event->type() == QEvent::LanguageChange) 22 | ui.retranslateUi(this); 23 | } 24 | 25 | void ExternalEditor::setEditor(const QString& _editorPath) 26 | { 27 | m_editorText->setText(_editorPath); 28 | } 29 | 30 | void ExternalEditor::setEditorArgs(const QString& _editorArgs) 31 | { 32 | m_editorArgs->setText(_editorArgs); 33 | } 34 | 35 | void ExternalEditor::run() 36 | { 37 | QString exe = m_editorText->text(); 38 | QString arg = m_editorArgs->text(); 39 | int r = exec(); 40 | if (r == QDialog::Rejected) 41 | { 42 | m_editorText->setText(exe); 43 | m_editorArgs->setText(arg); 44 | } 45 | } 46 | 47 | void ExternalEditor::browseForEditor() 48 | { 49 | QString exe = QFileDialog::getOpenFileName(this, tr("Select executable"), "", "exe files (*.exe)"); 50 | if (exe.size() != 0) 51 | m_editorText->setText(exe); 52 | } 53 | -------------------------------------------------------------------------------- /src/MTuner/src/external_editor.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_EXTERNALEDITOR_H 7 | #define RTM_MTUNER_EXTERNALEDITOR_H 8 | 9 | #include 10 | 11 | class ExternalEditor : public QDialog 12 | { 13 | Q_OBJECT 14 | 15 | QLineEdit* m_editorText; 16 | QLineEdit* m_editorArgs; 17 | 18 | public: 19 | ExternalEditor(QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 20 | 21 | void changeEvent(QEvent* _event); 22 | void setEditor(const QString& _editorPath); 23 | QString getEditorPath() const { return m_editorText->text(); } 24 | void setEditorArgs(const QString& _editorArgs); 25 | QString getEditorArgs() const { return m_editorArgs->text(); } 26 | void run(); 27 | 28 | public Q_SLOTS: 29 | void browseForEditor(); 30 | 31 | private: 32 | Ui::ExternalEditor ui; 33 | }; 34 | 35 | #endif // RTM_MTUNER_EXTERNALEDITOR_H 36 | -------------------------------------------------------------------------------- /src/MTuner/src/external_editor.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | ExternalEditor 4 | 5 | 6 | 7 | 0 8 | 0 9 | 571 10 | 138 11 | 12 | 13 | 14 | Setup external editor 15 | 16 | 17 | 18 | :/MTuner/resources/images/Editor64.png:/MTuner/resources/images/Editor64.png 19 | 20 | 21 | 22 | QLayout::SetMinAndMaxSize 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | Editor: 34 | 35 | 36 | 37 | 38 | 39 | 40 | Command line: 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | devenv.exe 54 | 55 | 56 | 57 | 58 | 59 | 60 | ... 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | "%F" /Command "Edit.GoTo %L" 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | Qt::Horizontal 81 | 82 | 83 | QDialogButtonBox::Cancel|QDialogButtonBox::Ok 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | buttonBox 97 | accepted() 98 | ExternalEditor 99 | accept() 100 | 101 | 102 | 227 103 | 87 104 | 105 | 106 | 157 107 | 104 108 | 109 | 110 | 111 | 112 | buttonBox 113 | rejected() 114 | ExternalEditor 115 | reject() 116 | 117 | 118 | 295 119 | 93 120 | 121 | 122 | 286 123 | 104 124 | 125 | 126 | 127 | 128 | toolButtonBrowseEditor 129 | clicked() 130 | ExternalEditor 131 | browseForEditor() 132 | 133 | 134 | 380 135 | 17 136 | 137 | 138 | 395 139 | 19 140 | 141 | 142 | 143 | 144 | 145 | browseForEditor() 146 | 147 | 148 | -------------------------------------------------------------------------------- /src/MTuner/src/gcc.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_GCC_H 7 | #define RTM_MTUNER_GCC_H 8 | 9 | #include 10 | 11 | struct Toolchain 12 | { 13 | QString m_name; 14 | QString m_Environment32; 15 | QString m_ToolchainPath32; 16 | QString m_ToolchainPrefix32; 17 | QString m_Environment64; 18 | QString m_ToolchainPath64; 19 | QString m_ToolchainPrefix64; 20 | rmem::ToolChain::Enum m_toolchain; 21 | }; 22 | 23 | class GCCSetup : public QDialog 24 | { 25 | Q_OBJECT 26 | 27 | QComboBox* m_toolchainCombo; 28 | QLabel* m_ToolchainNameLabel; 29 | QLineEdit* m_ToolchainNameEdit; 30 | QVector m_toolchains; 31 | 32 | QGroupBox* m_group32; 33 | QGroupBox* m_group64; 34 | QGroupBox* m_groupProDGps3; 35 | QLineEdit* m_leditEnv32; 36 | QLineEdit* m_leditBinutils32; 37 | QLineEdit* m_leditPrefix32; 38 | QLineEdit* m_leditEnv64; 39 | QLineEdit* m_leditBinutils64; 40 | QLineEdit* m_leditPrefix64; 41 | QLineEdit* m_leditEnvProDGps3; 42 | QLineEdit* m_leditBinutilsProDgps3; 43 | int m_currentToolchain; 44 | QLabel* m_labelOk64; 45 | QLabel* m_labelOk32; 46 | QLabel* m_labelOkProDGps3; 47 | QLabel* m_labelFound64; 48 | QLabel* m_labelFound32; 49 | QLabel* m_labelFoundProDGps3; 50 | 51 | public: 52 | GCCSetup(QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 53 | 54 | void changeEvent(QEvent* _event); 55 | int exec(); 56 | void readSettings(QSettings& _settings); 57 | void writeSettings(QSettings& _settings); 58 | bool isConfigured(rmem::ToolChain::Enum _toolchain, bool _64bit); 59 | void setupDefaultTC(QVector& _toolchains); 60 | int getNumToolchains() const { return m_toolchains.length(); } 61 | const Toolchain& getToolchain(int _index) const { return m_toolchains[_index]; } 62 | rdebug::Toolchain getToolchainInfo(rmem::ToolChain::Enum _toolchain, bool _64bit); 63 | 64 | public Q_SLOTS: 65 | void toolchainSelected(int _index); 66 | void toolchainRenamed(QString); 67 | void envEdited32(QString); 68 | void pathEdited32(QString); 69 | void pathBrowse32(); 70 | void prefixEdited32(QString); 71 | void envEdited64(QString); 72 | void pathEdited64(QString); 73 | void pathBrowse64(); 74 | void prefixEdited64(QString); 75 | void envEditedProDGps3(QString); 76 | void pathEditedProDGps3(QString); 77 | void pathBrowseProDGps3(); 78 | 79 | private: 80 | bool resolveToolchain(Toolchain& _toolchain, bool _64bit, rdebug::Toolchain& _tc); 81 | void setLabels(); 82 | 83 | Ui::GCCSetup ui; 84 | }; 85 | 86 | #endif // RTM_MTUNER_GCC_H 87 | -------------------------------------------------------------------------------- /src/MTuner/src/graph.cpp: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | Graph::Graph(QWidget* _parent, Qt::WindowFlags _flags) : 12 | QWidget(_parent, _flags) 13 | { 14 | ui.setupUi(this); 15 | 16 | m_graph = findChild("graphWidget"); 17 | 18 | connect(m_graph, SIGNAL(snapshotSelected()), this, SLOT(snapshotSelected())); 19 | connect(m_graph, SIGNAL(minMaxChanged()), this, SLOT(zoomChanged())); 20 | 21 | m_buttonZoomIn = findChild("buttonZoomIn"); 22 | connect(m_buttonZoomIn,SIGNAL(clicked()), m_graph, SLOT(zoomIn())); 23 | 24 | m_buttonZoomOut = findChild("buttonZoomOut"); 25 | connect(m_buttonZoomOut,SIGNAL(clicked()), m_graph, SLOT(zoomOut())); 26 | 27 | m_buttonZoomReset = findChild("buttonZoomReset"); 28 | connect(m_buttonZoomReset,SIGNAL(clicked()), m_graph, SLOT(zoomReset())); 29 | 30 | m_buttonZoomSelect = findChild("buttonZoomSelection"); 31 | connect(m_buttonZoomSelect,SIGNAL(clicked()), m_graph, SLOT(zoomSelect())); 32 | 33 | m_buttonAutoZoom = findChild("buttonZoomAuto"); 34 | connect(m_buttonAutoZoom, SIGNAL(clicked()), m_graph, SLOT(zoomAnimEvent())); 35 | 36 | m_scroll = findChild("scrollBar"); 37 | connect(m_scroll, SIGNAL(sliderMoved(int)), this, SLOT(scrollMoved(int))); 38 | 39 | m_graph->setGraph(this); 40 | 41 | setContext(nullptr, nullptr); 42 | } 43 | 44 | void Graph::changeEvent(QEvent* _event) 45 | { 46 | QWidget::changeEvent(_event); 47 | if (_event->type() == QEvent::LanguageChange) 48 | ui.retranslateUi(this); 49 | } 50 | 51 | void Graph::setContext(CaptureContext* _context, BinLoaderView* _binView) 52 | { 53 | m_context = _context; 54 | m_graph->setContext(_context, _binView); 55 | 56 | m_buttonZoomOut->setEnabled(false); 57 | m_buttonZoomReset->setEnabled(false); 58 | m_buttonZoomSelect->setEnabled(false); 59 | m_scroll->setEnabled(false); 60 | m_buttonZoomIn->setEnabled(_context == nullptr); 61 | m_buttonAutoZoom->setEnabled(_context == nullptr); 62 | } 63 | 64 | bool Graph::isAutoZoomSet() const 65 | { 66 | return m_buttonAutoZoom ? m_buttonAutoZoom->isChecked() : true; 67 | } 68 | 69 | void Graph::snapshotSelected() 70 | { 71 | if ((m_context->m_capture->getMinTime() != m_context->m_capture->getSnapshotTimeMin()) || 72 | (m_context->m_capture->getMaxTime() != m_context->m_capture->getSnapshotTimeMax())) 73 | { 74 | m_buttonZoomSelect->setEnabled(true); 75 | } 76 | else 77 | { 78 | m_buttonZoomSelect->setEnabled(false); 79 | } 80 | } 81 | 82 | void Graph::zoomChanged() 83 | { 84 | if ((m_context->m_capture->getMinTime() != m_graph->minTime()) || 85 | (m_context->m_capture->getMaxTime() != m_graph->maxTime())) 86 | { 87 | m_buttonZoomReset->setEnabled(true); 88 | m_buttonZoomOut->setEnabled(true); 89 | m_scroll->setEnabled(true); 90 | 91 | float visRange = m_graph->maxTime() - m_graph->minTime(); 92 | float hVisRange = visRange*0.5f; 93 | 94 | float newMin = m_context->m_capture->getMinTime() + hVisRange; 95 | float newMax = m_context->m_capture->getMaxTime() - hVisRange; 96 | 97 | m_scroll->setValue(m_scroll->maximum() * (m_graph->minTime() - m_context->m_capture->getMinTime()) / (newMax-newMin)); 98 | } 99 | else 100 | { 101 | m_buttonZoomReset->setEnabled(false); 102 | m_buttonZoomOut->setEnabled(false); 103 | m_scroll->setEnabled(false); 104 | m_scroll->setValue(0); 105 | } 106 | } 107 | 108 | void Graph::scrollMoved(int _value) 109 | { 110 | uint64_t visRange = m_graph->maxTime() - m_graph->minTime(); 111 | uint64_t fullRange = m_context->m_capture->getMaxTime() - m_context->m_capture->getMinTime(); 112 | uint64_t range = fullRange - visRange; 113 | float ratio = float(_value)/float(m_scroll->maximum()); 114 | uint64_t min = m_context->m_capture->getMinTime() + range*ratio; 115 | uint64_t max = min + visRange; 116 | min = qMax(min, m_context->m_capture->getMinTime()); 117 | max = qMin(max, m_context->m_capture->getMaxTime()); 118 | m_graph->setMinMaxTime( min, max ); 119 | } 120 | 121 | void Graph::highlightTime(uint64_t _time) 122 | { 123 | m_graph->highlightTime(_time); 124 | } 125 | 126 | void Graph::highlightRange(uint64_t _minTime, uint64_t _maxTime) 127 | { 128 | m_graph->highlightRange(_minTime, _maxTime); 129 | } 130 | -------------------------------------------------------------------------------- /src/MTuner/src/graph.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_GRAPH_H 7 | #define RTM_MTUNER_GRAPH_H 8 | 9 | #include 10 | 11 | class GraphWidget; 12 | class BinLoaderView; 13 | struct CaptureContext; 14 | 15 | class Graph : public QWidget 16 | { 17 | Q_OBJECT 18 | 19 | private: 20 | GraphWidget* m_graph; 21 | QToolButton* m_buttonZoomIn; 22 | QToolButton* m_buttonZoomOut; 23 | QToolButton* m_buttonZoomReset; 24 | QToolButton* m_buttonZoomSelect; 25 | QToolButton* m_buttonAutoZoom; 26 | QScrollBar* m_scroll; 27 | CaptureContext* m_context; 28 | 29 | public: 30 | Graph(QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 31 | 32 | void changeEvent(QEvent* _event); 33 | void setContext(CaptureContext* _context, BinLoaderView* _binView); 34 | bool isAutoZoomSet() const; 35 | inline GraphWidget* getGraphWidget() { return m_graph; } 36 | 37 | public Q_SLOTS: 38 | void snapshotSelected(); 39 | void zoomChanged(); 40 | void scrollMoved(int); 41 | void highlightTime(uint64_t); 42 | void highlightRange(uint64_t, uint64_t); 43 | 44 | private: 45 | Ui::Graph ui; 46 | }; 47 | 48 | #endif // RTM_MTUNER_GRAPH_H 49 | -------------------------------------------------------------------------------- /src/MTuner/src/graphcurve.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_GRAPHCURVE_H 7 | #define RTM_MTUNER_GRAPHCURVE_H 8 | 9 | class Graph; 10 | class GraphWidget; 11 | 12 | class GraphCurve : public QGraphicsItem 13 | { 14 | private: 15 | typedef std::vector GraphVec; 16 | 17 | Graph* m_graph; 18 | GraphWidget* m_graphWidget; 19 | uint64_t m_minUsage; 20 | uint64_t m_maxUsage; 21 | GraphVec m_graphValues; 22 | bool m_prevAutoZoom; 23 | uint64_t m_prevMinTime; 24 | uint64_t m_prevMaxTime; 25 | int64_t m_prevLeft; 26 | int64_t m_prevRight; 27 | uint64_t m_prevPeakUsage; 28 | uint64_t m_prevMinUsage; 29 | uint64_t m_prevPeakLive; 30 | uint64_t m_prevMinLive; 31 | 32 | public: 33 | GraphCurve(GraphWidget* _graphWidget); 34 | 35 | void setGraph(Graph* _graph); 36 | uint64_t getMinUsage() const { return m_prevMinUsage; } 37 | uint64_t getMaxUsage() const { return m_prevPeakUsage; } 38 | void parentResized() { prepareGeometryChange(); } 39 | 40 | /// QWidget 41 | virtual QRectF boundingRect() const; 42 | virtual void paint(QPainter* _painter, const QStyleOptionGraphicsItem* _option, QWidget* _widget); 43 | 44 | }; 45 | 46 | #endif // RTM_MTUNER_GRAPHCURVE_H 47 | -------------------------------------------------------------------------------- /src/MTuner/src/graphgrid.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_GRAPHGRID_H 7 | #define RTM_MTUNER_GRAPHGRID_H 8 | 9 | class GraphWidget; 10 | class GraphCurve; 11 | 12 | class GraphGrid : public QGraphicsItem 13 | { 14 | private: 15 | GraphWidget* m_graphWidget; 16 | GraphCurve* m_curve; 17 | 18 | public: 19 | GraphGrid(GraphWidget* _graphWidget, GraphCurve* _curve); 20 | 21 | void parentResized() { prepareGeometryChange(); } 22 | 23 | /// QWidget 24 | virtual QRectF boundingRect() const; 25 | virtual void paint(QPainter* _painter, const QStyleOptionGraphicsItem* _option, QWidget* _widget); 26 | }; 27 | 28 | #endif // RTM_MTUNER_GRAPHGRID_H 29 | -------------------------------------------------------------------------------- /src/MTuner/src/graphmarkers.cpp: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | GraphMarkers::GraphMarkers(GraphWidget* _graphWidget) 13 | { 14 | m_graphWidget = _graphWidget; 15 | } 16 | 17 | MarkerToolTip GraphMarkers::getTooltip(const QPointF& _point) const 18 | { 19 | MarkerToolTip ret; 20 | 21 | if (!m_graphWidget->getContext()) 22 | return ret; 23 | 24 | CaptureContext* ctx = m_graphWidget->getContext(); 25 | QRect rect = m_graphWidget->getDrawRect(); 26 | int bottom = rect.height() + rect.y(); 27 | 28 | const std::vector& mm = ctx->m_capture->getMemoryMarkers(); 29 | 30 | for (size_t i = 0; i < mm.size(); ++i) 31 | { 32 | const rtm::MemoryMarkerTime& mt = mm[i]; 33 | if (mt.m_time < m_graphWidget->minTime()) 34 | continue; 35 | if (mt.m_time > m_graphWidget->maxTime()) 36 | continue; 37 | 38 | int posX = m_graphWidget->mapTimeToPos(mt.m_time); 39 | QRectF markerRect = QRect(posX - 3, bottom + 3, 6, GraphWidget::s_marginBottom - 12); 40 | 41 | if (markerRect.contains(_point)) 42 | { 43 | ret.m_rect = markerRect; 44 | ret.m_text = ctx->m_capture->getMemoryMarkerName(mm[i].m_eventHash); 45 | ret.m_time = mm[i].m_time; 46 | ret.m_threadID = mm[i].m_threadID; 47 | return ret; 48 | } 49 | } 50 | return ret; 51 | } 52 | 53 | QRectF GraphMarkers::boundingRect() const 54 | { 55 | QSize sz = m_graphWidget->size(); 56 | return QRectF(-sz.width()/2, -sz.height()/2, sz.width(), sz.height()); 57 | } 58 | 59 | void GraphMarkers::paint(QPainter* _painter, const QStyleOptionGraphicsItem* _option, QWidget* _widget) 60 | { 61 | RTM_UNUSED(_option); 62 | RTM_UNUSED(_widget); 63 | 64 | if (!m_graphWidget->getContext()) 65 | return; 66 | 67 | _painter->setRenderHint(QPainter::Antialiasing, true); 68 | CaptureContext* ctx = m_graphWidget->getContext(); 69 | QRect rect = m_graphWidget->getDrawRect(); 70 | int bottom = rect.height() + rect.y(); 71 | 72 | uint64_t m1 = m_graphWidget->getMarkerFromTime(); 73 | uint64_t m2 = m_graphWidget->getMarkerToTime(); 74 | 75 | _painter->setPen(QPen(Qt::darkGray, 1.0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); 76 | const std::vector& mm = ctx->m_capture->getMemoryMarkers(); 77 | 78 | for (size_t i=0; i< mm.size(); ++i) 79 | { 80 | const rtm::MemoryMarkerTime& mt = mm[i]; 81 | if (mt.m_time < m_graphWidget->minTime()) 82 | continue; 83 | if (mt.m_time > m_graphWidget->maxTime()) 84 | continue; 85 | 86 | uint32_t color = ctx->m_capture->getMemoryMarkerColor(mm[i].m_eventHash); 87 | _painter->setBrush(QBrush(QColor( (color >> 16) & 0xff, (color >> 8) & 0xff, (color >> 0) & 0xff))); 88 | int posX = m_graphWidget->mapTimeToPos(mt.m_time); 89 | QRect markerRect = QRect(posX-3,bottom+3,6,GraphWidget::s_marginBottom-12); 90 | 91 | if ((m1 == mt.m_time) || (m2 == mt.m_time)) 92 | { 93 | if (m1 == mt.m_time) 94 | _painter->setPen(QPen(Qt::darkGreen, 1.0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); 95 | else 96 | _painter->setPen(QPen(Qt::darkRed, 1.0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); 97 | _painter->drawEllipse(markerRect.center(),6,6); 98 | } 99 | else 100 | { 101 | _painter->setPen(QPen(Qt::darkGray, 1.0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); 102 | _painter->drawRect(markerRect); 103 | } 104 | 105 | _painter->drawLine(posX, bottom-3, posX, bottom+3); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/MTuner/src/graphmarkers.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_GRAPHMARKERS_H 7 | #define RTM_MTUNER_GRAPHMARKERS_H 8 | 9 | class GraphWidget; 10 | 11 | struct MarkerToolTip 12 | { 13 | QRectF m_rect; 14 | float m_time; 15 | uint64_t m_threadID; 16 | std::string m_text; 17 | 18 | MarkerToolTip() {} 19 | MarkerToolTip(const QRect& _rect, float _time, uint64_t _threadID, const char* _text) : 20 | m_rect(_rect), 21 | m_time(_time), 22 | m_threadID(_threadID) 23 | { 24 | m_text = _text; 25 | } 26 | }; 27 | 28 | class GraphMarkers : public QGraphicsItem 29 | { 30 | private: 31 | GraphWidget* m_graphWidget; 32 | 33 | public: 34 | GraphMarkers(GraphWidget* _graphWidget); 35 | 36 | void parentResized() { prepareGeometryChange(); } 37 | MarkerToolTip getTooltip(const QPointF& _point) const; 38 | 39 | /// QWidget 40 | virtual QRectF boundingRect() const; 41 | virtual void paint(QPainter* _painter, const QStyleOptionGraphicsItem* _option, QWidget* _widget); 42 | }; 43 | 44 | #endif // RTM_MTUNER_GRAPHMARKERS_H 45 | -------------------------------------------------------------------------------- /src/MTuner/src/graphselect.cpp: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | GraphSelect::GraphSelect(GraphWidget* _graphWidget) 11 | { 12 | m_graphWidget = _graphWidget; 13 | m_minTime = 0; 14 | m_maxTime = 0; 15 | } 16 | 17 | void GraphSelect::setSelectRange(uint64_t _minTime, uint64_t _maxTime) 18 | { 19 | m_minTime = qMin(_minTime, _maxTime); 20 | m_maxTime = qMax(_minTime, _maxTime); 21 | } 22 | 23 | QRectF GraphSelect::boundingRect() const 24 | { 25 | QSize sz = m_graphWidget->size(); 26 | return QRectF(-sz.width()/2, -sz.height()/2, sz.width(), sz.height()); 27 | } 28 | 29 | void GraphSelect::paint(QPainter* _painter, const QStyleOptionGraphicsItem* _option, QWidget* _widget) 30 | { 31 | RTM_UNUSED(_option); 32 | RTM_UNUSED(_widget); 33 | if (!m_graphWidget->getContext()) 34 | return; 35 | 36 | if (m_minTime == m_maxTime) return; 37 | if (m_maxTime < m_graphWidget->minTime()) return; 38 | if (m_minTime > m_graphWidget->maxTime()) return; 39 | 40 | uint64_t minTime = qMax(m_minTime, m_graphWidget->minTime()); 41 | uint64_t maxTime = qMin(m_maxTime, m_graphWidget->maxTime()); 42 | 43 | QRect rect = m_graphWidget->getDrawRect(); 44 | int minX = m_graphWidget->mapTimeToPos(minTime); 45 | int maxX = m_graphWidget->mapTimeToPos(maxTime); 46 | 47 | int top = rect.y(); 48 | int bottom = rect.height() + rect.y(); 49 | 50 | _painter->setPen(Qt::NoPen); 51 | _painter->setBrush(QColor(50, 150, 170, 138)); 52 | _painter->drawRect(minX,top,maxX-minX,bottom-top); 53 | } 54 | -------------------------------------------------------------------------------- /src/MTuner/src/graphselect.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_GRAPHSELECT_H 7 | #define RTM_MTUNER_GRAPHSELECT_H 8 | 9 | class GraphWidget; 10 | 11 | class GraphSelect : public QGraphicsItem 12 | { 13 | private: 14 | GraphWidget* m_graphWidget; 15 | uint64_t m_minTime; 16 | uint64_t m_maxTime; 17 | 18 | public: 19 | GraphSelect(GraphWidget* _graphWidget); 20 | 21 | void parentResized() { prepareGeometryChange(); } 22 | void setSelectRange(uint64_t _minTime, uint64_t _maxTime); 23 | 24 | /// QWidget 25 | virtual QRectF boundingRect() const; 26 | virtual void paint(QPainter* _painter, const QStyleOptionGraphicsItem* _option, QWidget* _widget); 27 | 28 | }; 29 | 30 | #endif // RTM_MTUNER_GRAPHSELECT_H 31 | -------------------------------------------------------------------------------- /src/MTuner/src/graphwidget.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_GRAPHWIDGET_H 7 | #define RTM_MTUNER_GRAPHWIDGET_H 8 | 9 | class Graph; 10 | class GraphCurve; 11 | class GraphGrid; 12 | class GraphSelect; 13 | class GraphMarkers; 14 | class BinLoaderView; 15 | struct CaptureContext; 16 | 17 | class GraphWidget : public QGraphicsView 18 | { 19 | Q_OBJECT 20 | 21 | Q_PROPERTY(float minTime READ minTime WRITE setMinTime) 22 | Q_PROPERTY(float maxTime READ maxTime WRITE setMaxTime) 23 | Q_PROPERTY(float highlightIntensity READ highlightIntensity WRITE setHighlightIntensity) 24 | 25 | private: 26 | Graph* m_graph; 27 | QGraphicsScene* m_scene; 28 | QPoint m_dragStartPos; 29 | uint64_t m_minTime; 30 | uint64_t m_maxTime; 31 | uint64_t m_hightlightTime; 32 | uint64_t m_hightlightTimeEnd; 33 | float m_hightlightIntensity; 34 | QPropertyAnimation* m_highlightAnimation; 35 | bool m_LButtonDown; 36 | bool m_isDragging; 37 | bool m_RButtonDown; 38 | bool m_isPanning; 39 | uint64_t m_hoverMarkerTime; 40 | uint64_t m_markerSelectFromTime; 41 | uint64_t m_markerSelectToTime; 42 | CaptureContext* m_context; 43 | QVector m_curves; 44 | GraphGrid* m_grid; 45 | GraphSelect* m_select; 46 | GraphMarkers* m_markers; 47 | QMenu* m_contextMenu; 48 | QAction* m_actionZoomToSelection; 49 | QAction* m_actionZoomReset; 50 | bool m_inContextMenu; 51 | QMenu* m_contextMenuMarker; 52 | QAction* m_actionSnapSelectionToMarker; 53 | QAction* m_actionSelectFromMarker; 54 | QAction* m_actionSelectToMarker; 55 | QLocale m_locale; 56 | QLabel* m_toolTipLabel; 57 | public: 58 | static const int s_marginLeft = 45; 59 | static const int s_marginRight = 21; 60 | static const int s_marginTop = 15; 61 | static const int s_marginBottom = 27; 62 | 63 | GraphWidget(QWidget* _parent = 0); 64 | 65 | void changeEvent(QEvent* _event); 66 | void setGraph(Graph* _graph); 67 | uint64_t minTime() { return m_minTime; } 68 | uint64_t maxTime() { return m_maxTime; } 69 | float highlightIntensity() { return m_hightlightIntensity; } 70 | void setHighlightIntensity(float inI) { m_hightlightIntensity = inI; } 71 | void setMinTime(uint64_t _minTime); 72 | void setMaxTime(uint64_t _maxTime); 73 | void setMinMaxTime( uint64_t _minTime, uint64_t _maxTime); 74 | uint64_t getMarkerFromTime() const { return m_markerSelectFromTime; } 75 | uint64_t getMarkerToTime() const { return m_markerSelectToTime; } 76 | void setContext(CaptureContext* _context, BinLoaderView* _view); 77 | CaptureContext* getContext() { return m_context; }; 78 | QRect getDrawRect() const; 79 | uint64_t mapPosToTime(int _x) const; 80 | int mapTimeToPos(uint64_t _x) const; 81 | void highlightTime(uint64_t _time); 82 | void highlightRange(uint64_t _minTime, uint64_t _maxTime); 83 | void animateHighlight(); 84 | uint64_t getHighlightTime() const { return m_hightlightTime; } 85 | uint64_t getHighlightTimeEnd() const { return m_hightlightTimeEnd; } 86 | void zoomIn(uint64_t _time); 87 | void zoomOut(uint64_t _time); 88 | void updateToolTip(const QPoint& _position); 89 | 90 | /// QGraphicsView 91 | void drawBackground(QPainter* _painter, const QRectF& _rect); 92 | 93 | /// QWidget 94 | void resizeEvent(QResizeEvent* _event); 95 | void wheelEvent(QWheelEvent* _event); 96 | void mousePressEvent(QMouseEvent* _event); 97 | void mouseMoveEvent(QMouseEvent* _event); 98 | void mouseReleaseEvent(QMouseEvent* _event); 99 | void contextMenuEvent(QContextMenuEvent* _event); 100 | void leaveEvent(QEvent*) { m_toolTipLabel->hide(); } 101 | 102 | protected: 103 | void mouseMovement(const QPoint& _position, Qt::MouseButtons _buttons = Qt::NoButton); 104 | void createCustomContextMenu(); 105 | void animateRange(uint64_t _min, uint64_t _max); 106 | 107 | bool event(QEvent *event); 108 | 109 | public Q_SLOTS: 110 | void zoomIn(); 111 | void zoomOut(); 112 | void zoomReset(); 113 | void zoomSelect(); 114 | void zoomAnimEvent(); 115 | void markerSnapTo(); 116 | void markerSelectFrom(); 117 | void markerSelectTo(); 118 | void showToolTip(); 119 | void leaveContextMenu(); 120 | void selectFromTimes(uint64_t, uint64_t); 121 | 122 | Q_SIGNALS: 123 | void snapshotSelected(); 124 | void minMaxChanged(); 125 | }; 126 | 127 | #endif // RTM_MTUNER_GRAPHWIDGET_H 128 | -------------------------------------------------------------------------------- /src/MTuner/src/grouplist.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | GroupListWidget 4 | 5 | 6 | 7 | 0 8 | 0 9 | 897 10 | 614 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 0 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | BigTable 28 | QWidget 29 |
../src/bigtable.h
30 | 1 31 |
32 |
33 | 34 | 35 |
36 | -------------------------------------------------------------------------------- /src/MTuner/src/grouplistwidget.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_GROUPLISTWIDGET_H 7 | #define RTM_MTUNER_GROUPLISTWIDGET_H 8 | 9 | #include 10 | 11 | class GroupTableSource; 12 | struct CaptureContext; 13 | 14 | struct GroupMapping 15 | { 16 | typedef std::vector MemoryOperationPtrArray; 17 | 18 | uint32_t m_columnIndex; 19 | MemoryOperationPtrArray* m_allGroups; 20 | std::vector m_sortedIdx; 21 | }; 22 | 23 | class GroupList : public QWidget 24 | { 25 | Q_OBJECT 26 | 27 | private: 28 | CaptureContext* m_context; 29 | BigTable* m_groupList; 30 | GroupTableSource* m_tableSource; 31 | bool m_enableFiltering; 32 | uint64_t m_lastRange[2]; 33 | QAction* m_selectAction; 34 | QMenu* m_contextMenu; 35 | 36 | int m_savedColumn; 37 | Qt::SortOrder m_savedOrder; 38 | QByteArray m_headerState; 39 | QString m_settingsGroupName; 40 | 41 | public: 42 | GroupList(QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 43 | ~GroupList(); 44 | 45 | void changeEvent(QEvent* _event); 46 | void setContext(CaptureContext* _context); 47 | void setFilteringState(bool _state); 48 | bool getFilteringState() const; 49 | void loadState(QSettings& _settings, const QString& _name, bool _resetGeometry); 50 | void saveState(QSettings& _settings); 51 | void mouseMoveEvent(QMouseEvent* _event); 52 | 53 | Q_SIGNALS: 54 | void setStackTrace(rtm::StackTrace**, int); 55 | void usageSortingDone(GroupMapping*); 56 | void peakUsageSortingDone(GroupMapping*); 57 | void peakCountSortingDone(GroupMapping*); 58 | void leaksSortingDone(GroupMapping*); 59 | void highlightTime(uint64_t); 60 | void highlightRange(uint64_t, uint64_t); 61 | void selectRange(uint64_t, uint64_t); 62 | 63 | public Q_SLOTS: 64 | void selectionChanged(void*); 65 | void groupRightClick(void*, const QPoint&); 66 | void sortingDoneUsage(); 67 | void sortingDonePeakUsage(); 68 | void sortingDonePeakCount(); 69 | void sortingDoneLeaks(); 70 | void selectTriggered(); 71 | 72 | private: 73 | Ui::GroupListWidget ui; 74 | }; 75 | 76 | #endif // RTM_MTUNER_GROUPLISTWIDGET_H 77 | -------------------------------------------------------------------------------- /src/MTuner/src/heapswidget.cpp: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | HeapsWidget::HeapsWidget(QWidget* _parent, Qt::WindowFlags _flags) 11 | : QWidget(_parent, _flags) 12 | , m_currentItem(0) 13 | { 14 | ui.setupUi(this); 15 | 16 | m_treeWidget = findChild("treeWidget"); 17 | connect(m_treeWidget, SIGNAL(itemSelectionChanged()), this, SLOT(selectionChanged())); 18 | } 19 | 20 | void HeapsWidget::changeEvent(QEvent* _event) 21 | { 22 | QWidget::changeEvent(_event); 23 | if (_event->type() == QEvent::LanguageChange) 24 | ui.retranslateUi(this); 25 | } 26 | 27 | void HeapsWidget::setContext(CaptureContext* _context) 28 | { 29 | if (m_context == _context) 30 | return; 31 | 32 | m_context = _context; 33 | 34 | if (m_context) 35 | { 36 | m_treeWidget->clear(); 37 | rtm::HeapsType& heaps = m_context->m_capture->getHeaps(); 38 | rtm::HeapsType::iterator it = heaps.begin(); 39 | rtm::HeapsType::iterator end = heaps.end(); 40 | 41 | while (it != end) 42 | { 43 | QTreeWidgetItem* item = new QTreeWidgetItem(QStringList() 44 | << ("0x" + QString::number((qlonglong)it->first,16)) 45 | << QString(it->second.c_str())); 46 | item->setData(0, Qt::UserRole, (qlonglong)it->first); 47 | m_treeWidget->addTopLevelItem(item); 48 | ++it; 49 | } 50 | } 51 | else 52 | m_treeWidget->clear(); 53 | } 54 | 55 | void HeapsWidget::selectionChanged() 56 | { 57 | QTreeWidgetItem* currItem = m_treeWidget->currentItem(); 58 | if (m_currentItem == currItem) 59 | { 60 | m_currentItem = 0; 61 | m_treeWidget->setCurrentItem(0); 62 | emit heapSelected((uint64_t)-1); 63 | } 64 | else 65 | { 66 | m_currentItem = currItem; 67 | m_treeWidget->setCurrentItem(currItem); 68 | uint64_t address = currItem->data(0, Qt::UserRole).toULongLong(); 69 | emit heapSelected(address); 70 | } 71 | } 72 | 73 | void HeapsWidget::setCurrentHeap(uint64_t _handle) 74 | { 75 | QTreeWidgetItemIterator it(m_treeWidget); 76 | while (*it) 77 | { 78 | if ((*it)->data(0,Qt::UserRole).toULongLong() == _handle) 79 | { 80 | (*it)->setSelected(true); 81 | return; 82 | } 83 | ++it; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/MTuner/src/heapswidget.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_HEAPSWIDGET_H 7 | #define RTM_MTUNER_HEAPSWIDGET_H 8 | 9 | #include 10 | 11 | struct CaptureContext; 12 | 13 | class HeapsWidget : public QWidget 14 | { 15 | Q_OBJECT 16 | 17 | private: 18 | QTreeWidget* m_treeWidget; 19 | QTreeWidgetItem*m_currentItem; 20 | CaptureContext* m_context; 21 | 22 | public: 23 | HeapsWidget(QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 24 | 25 | void changeEvent(QEvent* _event); 26 | void setContext(CaptureContext* _capture); 27 | void setCurrentHeap(uint64_t _handle); 28 | 29 | public Q_SLOTS: 30 | void selectionChanged(); 31 | 32 | Q_SIGNALS: 33 | void heapSelected(uint64_t); 34 | 35 | private: 36 | Ui::HeapsWidget ui; 37 | }; 38 | 39 | #endif // RTM_MTUNER_HEAPSWIDGET_H 40 | -------------------------------------------------------------------------------- /src/MTuner/src/heapswidget.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | HeapsWidget 4 | 5 | 6 | 7 | 0 8 | 0 9 | 302 10 | 316 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 0 19 | 20 | 21 | 0 22 | 23 | 24 | 0 25 | 26 | 27 | 0 28 | 29 | 30 | 31 | 32 | Qt::NoFocus 33 | 34 | 35 | 2 36 | 37 | 38 | 100 39 | 40 | 41 | 42 | Handle 43 | 44 | 45 | 46 | 47 | Name 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /src/MTuner/src/highlighter.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_HIGHLIGHTER_H 7 | #define RTM_MTUNER_HIGHLIGHTER_H 8 | 9 | class Highlighter : public QSyntaxHighlighter 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | Highlighter(QTextDocument* _parent = 0); 15 | 16 | protected: 17 | void highlightBlock(const QString& _text); 18 | 19 | private: 20 | struct HighlightingRule 21 | { 22 | QRegularExpression m_pattern; 23 | QTextCharFormat m_format; 24 | }; 25 | 26 | QVector m_highlightingRules; 27 | QTextCharFormat m_keywordFormat; 28 | QTextCharFormat m_keywordFormat2; 29 | QTextCharFormat m_classFormat; 30 | QTextCharFormat m_singleLineCommentFormat; 31 | QTextCharFormat m_multiLineCommentFormat; 32 | QTextCharFormat m_quotationFormat; 33 | QTextCharFormat m_includeFormat; 34 | QTextCharFormat m_functionFormat; 35 | QTextCharFormat m_functionFormat2; 36 | QTextCharFormat m_functionFormat3; 37 | QTextCharFormat m_preprocessorFormat; 38 | QTextCharFormat m_preprocessorFormat2; 39 | QTextCharFormat m_preprocessorFormat3; 40 | }; 41 | 42 | #endif // RTM_MTUNER_HIGHLIGHTER_H 43 | -------------------------------------------------------------------------------- /src/MTuner/src/histogram.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_HISTOGRAM_H 7 | #define RTM_MTUNER_HISTOGRAM_H 8 | 9 | class HistogramView; 10 | 11 | struct HistogramToolTip 12 | { 13 | QRectF m_rect; 14 | QString m_text; 15 | int m_bin; 16 | 17 | HistogramToolTip() {} 18 | HistogramToolTip(const QRect& _rect, const QString& _string, int _bin) : 19 | m_rect(_rect), 20 | m_text(_string), 21 | m_bin(_bin) 22 | {} 23 | }; 24 | 25 | struct DisplayMode 26 | { 27 | enum Enum 28 | { 29 | Global, 30 | Snapshot, 31 | Both 32 | }; 33 | }; 34 | 35 | struct HistogramType 36 | { 37 | enum Enum 38 | { 39 | Size, 40 | Overhead, 41 | Count 42 | }; 43 | }; 44 | 45 | class Histogram : public QGraphicsItem 46 | { 47 | private: 48 | HistogramView* m_histogramWidget; 49 | DisplayMode::Enum m_displayMode; 50 | HistogramType::Enum m_type; 51 | bool m_showPeaks; 52 | bool m_scalePeaks; 53 | QVector m_toolTips; 54 | QPoint m_highlight; 55 | int m_highlightBin; 56 | QLocale m_locale; 57 | 58 | public: 59 | Histogram(HistogramView* _graphWidget); 60 | 61 | void parentResized() { prepareGeometryChange(); } 62 | void setDisplayMode(DisplayMode::Enum _mode) { m_displayMode = _mode; parentResized(); } 63 | void setHistogramType(HistogramType::Enum _type) { m_type = _type; parentResized(); } 64 | void setPeaks(bool _show) { m_showPeaks = _show; parentResized(); } 65 | void setScale(bool _scale) { m_scalePeaks = _scale; parentResized(); } 66 | void setHighlight(const QPoint& _point, int _binIndex) { m_highlight = _point; m_highlightBin = _binIndex; parentResized(); } 67 | int getHighlightIndex() const { return m_highlightBin; } 68 | 69 | const QVector& getTooltips() const { return m_toolTips; } 70 | 71 | /// QWidget 72 | virtual QRectF boundingRect() const; 73 | virtual void paint(QPainter* _painter, const QStyleOptionGraphicsItem* _option, QWidget* _widget); 74 | 75 | private: 76 | QString fromVal(int _val); 77 | uint64_t getMaxValue(rtm::MemoryStats& _stats, HistogramType::Enum _type, bool _usePeak); 78 | uint64_t getValue(rtm::MemoryStats& _stats, HistogramType::Enum _type, int _bin, bool _peak); 79 | QString getTypeString(HistogramType::Enum _type, uint64_t _val); 80 | }; 81 | 82 | #endif // RTM_MTUNER_HISTOGRAM_H 83 | -------------------------------------------------------------------------------- /src/MTuner/src/histogram.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | HistogramWidgetClass 4 | 5 | 6 | 7 | 0 8 | 0 9 | 434 10 | 149 11 | 12 | 13 | 14 | 15 | 0 16 | 0 17 | 18 | 19 | 20 | Form 21 | 22 | 23 | 24 | :/MTuner/resources/images/Histogram64.png:/MTuner/resources/images/Histogram64.png 25 | 26 | 27 | 28 | 0 29 | 30 | 31 | QLayout::SetMinimumSize 32 | 33 | 34 | 0 35 | 36 | 37 | 38 | 39 | 40 | 0 41 | 0 42 | 43 | 44 | 45 | QGraphicsView::CacheBackground 46 | 47 | 48 | 49 | 50 | 51 | 52 | QLayout::SetMinimumSize 53 | 54 | 55 | 56 | 57 | 58 | 0 59 | 0 60 | 61 | 62 | 63 | 64 | Memory usage 65 | 66 | 67 | 68 | 69 | Allocation overhead 70 | 71 | 72 | 73 | 74 | Number of allocations 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 0 84 | 0 85 | 86 | 87 | 88 | Select which time range to show histograms for 89 | 90 | 91 | 92 | Global histogram 93 | 94 | 95 | 96 | 97 | Snapshot histogram 98 | 99 | 100 | 101 | 102 | Global and snapshot histogram 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | Shows peak values alongside current values 111 | 112 | 113 | Show peaks 114 | 115 | 116 | 117 | 118 | 119 | 120 | If checked, all values are normalized to peak values. 121 | Otherwise, relative scale is used. 122 | 123 | 124 | Scale to peaks 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | HistogramView 135 | QGraphicsView 136 |
../../src/histogramview.h
137 |
138 |
139 | 140 | 141 | 142 | 143 |
144 | -------------------------------------------------------------------------------- /src/MTuner/src/histogramview.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_HISTOGRAMVIEW_H 7 | #define RTM_MTUNER_HISTOGRAMVIEW_H 8 | 9 | class Histogram; 10 | struct CaptureContext; 11 | 12 | class HistogramView : public QGraphicsView 13 | { 14 | Q_OBJECT 15 | 16 | private: 17 | QGraphicsScene* m_scene; 18 | CaptureContext* m_context; 19 | Histogram* m_histogram; 20 | QLabel* m_toolTipLabel; 21 | int m_mode; 22 | bool m_showPeaks; 23 | int m_histogramType; 24 | 25 | public: 26 | static const int s_marginLeft = 45; 27 | static const int s_marginRight = 30; 28 | static const int s_marginTop = 23; 29 | static const int s_marginBottom = 46; 30 | 31 | HistogramView(QWidget* _parent = 0); 32 | 33 | QRect getDrawRect() const; 34 | void setContext(CaptureContext* _context); 35 | CaptureContext* getContext() { return m_context; } 36 | Histogram* getHistogram() { return m_histogram; } 37 | void updateUI(); 38 | 39 | void drawBackground(QPainter* _painter, const QRectF& _rect); 40 | 41 | void resizeEvent(QResizeEvent* _event); 42 | void mousePressEvent(QMouseEvent* _event); 43 | void mouseMoveEvent(QMouseEvent* _event); 44 | void mouseReleaseEvent(QMouseEvent* _event); 45 | void leaveEvent(QEvent* _event); 46 | 47 | Q_SIGNALS: 48 | void binClicked(); 49 | }; 50 | 51 | #endif // RTM_MTUNER_HISTOGRAMVIEW_H 52 | -------------------------------------------------------------------------------- /src/MTuner/src/histogramwidget.cpp: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | HistogramWidget::HistogramWidget(QWidget* _parent, Qt::WindowFlags _flags) : 13 | QWidget(_parent, _flags) 14 | { 15 | ui.setupUi(this); 16 | 17 | m_histogramView = findChild("graphicsView"); 18 | connect(m_histogramView, SIGNAL(binClicked()), this, SIGNAL(binClicked())); 19 | 20 | m_comboType = findChild("comboType"); 21 | connect(m_comboType, SIGNAL(activated(int)), this, SLOT(displayTypeChanged(int))); 22 | 23 | m_comboHist = findChild("comboHistogram"); 24 | connect(m_comboHist, SIGNAL(activated(int)), this, SLOT(displayModeChanged(int))); 25 | 26 | m_chkPeaks = findChild("checkBoxPeaks"); 27 | connect(m_chkPeaks, SIGNAL(stateChanged(int)), this, SLOT(showPeaksChanged(int))); 28 | 29 | m_chkScale = findChild("checkBoxScale"); 30 | connect(m_chkScale, SIGNAL(stateChanged(int)), this, SLOT(scalePeaksChanged(int))); 31 | 32 | setContext(NULL,NULL); 33 | } 34 | 35 | void HistogramWidget::changeEvent(QEvent* _event) 36 | { 37 | QWidget::changeEvent(_event); 38 | if (_event->type() == QEvent::LanguageChange) 39 | ui.retranslateUi(this); 40 | } 41 | 42 | void HistogramWidget::setContext(CaptureContext* _capture, BinLoaderView* _binView) 43 | { 44 | m_binView = _binView; 45 | 46 | m_comboType->setEnabled(_capture != nullptr); 47 | m_comboHist->setEnabled(_capture != nullptr); 48 | m_chkPeaks->setEnabled(_capture != nullptr); 49 | m_chkScale->setEnabled(_capture != nullptr); 50 | m_histogramView->setContext(_capture); 51 | 52 | if (_capture) 53 | { 54 | displayTypeChanged(m_binView->getHistogramType()); 55 | displayModeChanged(m_binView->getHistogramMode()); 56 | showPeaksChanged(m_binView->getHistogramPeaks()?1:0); 57 | scalePeaksChanged(m_binView->getHistogramScale()?1:0); 58 | } 59 | else 60 | { 61 | displayTypeChanged(0); 62 | displayModeChanged(0); 63 | showPeaksChanged(0); 64 | scalePeaksChanged(0); 65 | } 66 | } 67 | 68 | void HistogramWidget::updateUI() 69 | { 70 | if (m_histogramView) 71 | m_histogramView->updateUI(); 72 | } 73 | 74 | void HistogramWidget::displayTypeChanged(int _index) 75 | { 76 | Histogram* h = m_histogramView->getHistogram(); 77 | switch(_index) 78 | { 79 | case 0: h->setHistogramType(HistogramType::Size); break; 80 | case 1: h->setHistogramType(HistogramType::Overhead); break; 81 | case 2: h->setHistogramType(HistogramType::Count); break; 82 | }; 83 | if (m_binView) 84 | m_binView->setHistogramType(_index); 85 | m_comboType->setCurrentIndex(_index); 86 | } 87 | 88 | void HistogramWidget::displayModeChanged(int _index) 89 | { 90 | Histogram* h = m_histogramView->getHistogram(); 91 | switch(_index) 92 | { 93 | case 0: h->setDisplayMode(DisplayMode::Global); break; 94 | case 1: h->setDisplayMode(DisplayMode::Snapshot); break; 95 | case 2: h->setDisplayMode(DisplayMode::Both); break; 96 | }; 97 | if (m_binView) 98 | m_binView->setHistogramMode(_index); 99 | m_comboHist->setCurrentIndex(_index); 100 | } 101 | 102 | void HistogramWidget::showPeaksChanged(int _state) 103 | { 104 | Histogram* h = m_histogramView->getHistogram(); 105 | h->setPeaks(_state!=0); 106 | if (m_binView) 107 | m_binView->setHistogramPeaks(_state!=0); 108 | m_chkPeaks->setChecked(_state!=0); 109 | } 110 | 111 | void HistogramWidget::scalePeaksChanged(int _state) 112 | { 113 | Histogram* h = m_histogramView->getHistogram(); 114 | h->setScale(_state!=0); 115 | if (m_binView) 116 | m_binView->setHistogramScale(_state!=0); 117 | m_chkScale->setChecked(_state!=0); 118 | } 119 | -------------------------------------------------------------------------------- /src/MTuner/src/histogramwidget.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_HISTOGRAMWIDGET_H 7 | #define RTM_MTUNER_HISTOGRAMWIDGET_H 8 | 9 | #include 10 | 11 | class HistogramView; 12 | class BinLoaderView; 13 | 14 | class HistogramWidget : public QWidget 15 | { 16 | Q_OBJECT 17 | 18 | private: 19 | QComboBox* m_comboType; 20 | QComboBox* m_comboHist; 21 | QCheckBox* m_chkPeaks; 22 | QCheckBox* m_chkScale; 23 | HistogramView* m_histogramView; 24 | BinLoaderView* m_binView; 25 | 26 | public: 27 | HistogramWidget(QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 28 | 29 | void changeEvent(QEvent* _event); 30 | void setContext(CaptureContext* _context, BinLoaderView* _binView); 31 | 32 | public Q_SLOTS: 33 | void updateUI(); 34 | void displayTypeChanged(int _index); 35 | void displayModeChanged(int _index); 36 | void showPeaksChanged(int _state); 37 | void scalePeaksChanged(int _state); 38 | 39 | Q_SIGNALS: 40 | void binClicked(); 41 | 42 | private: 43 | Ui::HistogramWidgetClass ui; 44 | }; 45 | 46 | #endif // RTM_MTUNER_HISTOGRAMWIDGET_H 47 | -------------------------------------------------------------------------------- /src/MTuner/src/hotspots.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_HOTSPOTS_H 7 | #define RTM_MTUNER_HOTSPOTS_H 8 | 9 | #include 10 | #include 11 | 12 | class TableKeyWatcher : public QObject 13 | { 14 | Q_OBJECT 15 | 16 | bool eventFilter(QObject* _receiver, QEvent* _event) override 17 | { 18 | QTableWidget* table = qobject_cast(_receiver); 19 | if (table && _event->type() == QEvent::KeyPress) 20 | { 21 | auto keyEvent = static_cast(_event); 22 | if ((keyEvent->key() == Qt::Key_Up) || 23 | (keyEvent->key() == Qt::Key_Down)) 24 | { 25 | emit updateStackTrace(table); 26 | } 27 | } 28 | return false; 29 | } 30 | 31 | Q_SIGNALS: 32 | void updateStackTrace(QTableWidget*); 33 | 34 | public: 35 | void installOn(QTableWidget* _table) 36 | { 37 | _table->installEventFilter(this); 38 | } 39 | }; 40 | 41 | class HotspotsWidget : public QWidget 42 | { 43 | Q_OBJECT 44 | 45 | QTableWidget* m_usageTable; 46 | GroupMapping* m_usageMapping; 47 | QTableWidget* m_peakUsageTable; 48 | GroupMapping* m_peakUsageMapping; 49 | QTableWidget* m_peakCountTable; 50 | GroupMapping* m_peakCountUsageMapping; 51 | QTableWidget* m_leaksTable; 52 | GroupMapping* m_leaksMapping; 53 | TableKeyWatcher* m_tableKeyWatch; 54 | 55 | public: 56 | HotspotsWidget(QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 57 | 58 | void changeEvent(QEvent* _event); 59 | 60 | Q_SIGNALS: 61 | void setStackTrace(rtm::StackTrace**, int); 62 | void highlightRange(uint64_t, uint64_t); 63 | 64 | public Q_SLOTS: 65 | void usageSortingDone(GroupMapping*); 66 | void peakUsageSortingDone(GroupMapping*); 67 | void peakCountSortingDone(GroupMapping*); 68 | void leaksSortingDone(GroupMapping*); 69 | void rowSelected(QTableWidgetItem*); 70 | void updateStackTrace(QTableWidget*); 71 | 72 | private: 73 | Ui::hotspotWidget ui; 74 | }; 75 | 76 | #endif // RTM_MTUNER_HOTSPOTS_H 77 | -------------------------------------------------------------------------------- /src/MTuner/src/inject.cpp: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #include 7 | #include 8 | 9 | Inject::Inject(QWidget* _parent, Qt::WindowFlags _flags) 10 | : QDialog(_parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint) 11 | { 12 | RTM_UNUSED(_flags); 13 | ui.setupUi(this); 14 | ui.capture->setEnabled(false); 15 | ui.capture->setChecked(true); 16 | } 17 | 18 | void Inject::changeEvent(QEvent* _event) 19 | { 20 | QDialog::changeEvent(_event); 21 | if (_event->type() == QEvent::LanguageChange) 22 | ui.retranslateUi(this); 23 | } 24 | 25 | bool Inject::loadAfterCapture() 26 | { 27 | return (ui.capture->isEnabled() || (ui.allocatorCombo->currentIndex() == 0)) && ui.capture->isChecked() && ui.loadAfterCapture->isChecked(); 28 | } 29 | 30 | void Inject::capture(bool _shouldCapture) 31 | { 32 | ui.loadAfterCapture->setEnabled(_shouldCapture); 33 | } 34 | 35 | void Inject::allocatorChanged(int _index) 36 | { 37 | ui.capture->setEnabled(_index > 0); 38 | if (_index == 0) 39 | { 40 | ui.capture->setChecked(true); 41 | ui.loadAfterCapture->setEnabled(true); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/MTuner/src/inject.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_INJECT_H 7 | #define RTM_MTUNER_INJECT_H 8 | 9 | #include 10 | 11 | class Inject : public QDialog 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | Inject(QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 17 | 18 | void changeEvent(QEvent* _event); 19 | int getAllocator() { return ui.allocatorCombo->currentIndex(); } 20 | bool shouldCapture() { return ui.capture->isChecked(); } 21 | bool loadAfterCapture(); 22 | 23 | public Q_SLOTS: 24 | void capture(bool); 25 | void allocatorChanged(int); 26 | 27 | private: 28 | Ui::Inject ui; 29 | }; 30 | 31 | #endif // RTM_MTUNER_INJECT_H 32 | -------------------------------------------------------------------------------- /src/MTuner/src/inject.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Inject 4 | 5 | 6 | 7 | 0 8 | 0 9 | 176 10 | 116 11 | 12 | 13 | 14 | Inject and run 15 | 16 | 17 | 18 | :/MTuner/resources/images/Run.png:/MTuner/resources/images/Run.png 19 | 20 | 21 | true 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | Allocator: 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | No change / system 38 | 39 | 40 | 41 | 42 | stomp overrun 43 | 44 | 45 | 46 | 47 | stomp underrun 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | Qt::Horizontal 56 | 57 | 58 | 59 | 40 60 | 20 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | Capture memory profile 71 | 72 | 73 | true 74 | 75 | 76 | 77 | 78 | 79 | 80 | Load memory profile after capture 81 | 82 | 83 | true 84 | 85 | 86 | 87 | 88 | 89 | 90 | false 91 | 92 | 93 | Memory overwrite detection 94 | 95 | 96 | 97 | 98 | 99 | 100 | Qt::Horizontal 101 | 102 | 103 | QDialogButtonBox::Cancel|QDialogButtonBox::Ok 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | buttonBox 115 | accepted() 116 | Inject 117 | accept() 118 | 119 | 120 | 169 121 | 109 122 | 123 | 124 | 157 125 | 115 126 | 127 | 128 | 129 | 130 | buttonBox 131 | rejected() 132 | Inject 133 | reject() 134 | 135 | 136 | 169 137 | 109 138 | 139 | 140 | 175 141 | 115 142 | 143 | 144 | 145 | 146 | allocatorCombo 147 | currentIndexChanged(int) 148 | Inject 149 | allocatorChanged(int) 150 | 151 | 152 | 118 153 | 24 154 | 155 | 156 | 163 157 | 19 158 | 159 | 160 | 161 | 162 | capture 163 | clicked(bool) 164 | Inject 165 | capture(bool) 166 | 167 | 168 | 90 169 | 47 170 | 171 | 172 | 154 173 | 71 174 | 175 | 176 | 177 | 178 | 179 | allocatorChanged(int) 180 | capture(bool) 181 | 182 | 183 | -------------------------------------------------------------------------------- /src/MTuner/src/loader/binloader.cpp: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define LZ5_DISABLE_DEPRECATE_WARNINGS 12 | #include 13 | 14 | #if RTM_COMPILER_MSVC 15 | #pragma intrinsic (memcpy) 16 | #endif // RTM_COMPILER_MSVC 17 | 18 | namespace rtm { 19 | 20 | BinLoader::BinLoader(FILE* _file, bool _compressed) : 21 | m_file(_file) 22 | { 23 | m_compressed = _compressed; 24 | m_bytesRead = 0; 25 | m_srcData = new uint8_t[rmem::MemoryHook::BufferSize]; 26 | m_srcDataSize = rmem::MemoryHook::BufferSize; 27 | m_data = new uint8_t[rmem::MemoryHook::BufferSize]; 28 | m_dataPos = 0; 29 | m_dataSize = rmem::MemoryHook::BufferSize; 30 | m_dataAvailable = 0; 31 | 32 | if (_compressed) 33 | loadChunk(); 34 | } 35 | 36 | BinLoader::~BinLoader() 37 | { 38 | delete[] m_data; 39 | delete[] m_srcData; 40 | } 41 | 42 | bool BinLoader::eof() 43 | { 44 | if (m_compressed) 45 | return (m_dataPos == m_dataAvailable); 46 | 47 | return (feof(m_file) != 0); 48 | } 49 | 50 | uint64_t BinLoader::tell() 51 | { 52 | if (m_compressed) 53 | return m_bytesRead + m_dataPos; 54 | else 55 | return fileTell(); 56 | } 57 | 58 | uint64_t BinLoader::fileTell() 59 | { 60 | #if RTM_PLATFORM_WINDOWS 61 | uint64_t pos = (uint64_t)_ftelli64(m_file); 62 | #elif RTM_PLATFORM_LINUX 63 | uint64_t pos = (uint64_t)ftello64(m_file); 64 | #elif RTM_PLATFORM_OSX 65 | uint64_t pos = (uint64_t)ftello(m_file); 66 | #endif 67 | return pos; 68 | } 69 | 70 | int BinLoader::read(void* _ptr, size_t _size) 71 | { 72 | if (!m_compressed) 73 | return (int)fread(_ptr, _size, 1, m_file); 74 | 75 | const int32_t bytesLeft = m_dataAvailable - m_dataPos; 76 | 77 | if (bytesLeft > (int32_t)_size) 78 | { 79 | memcpy(_ptr, &m_data[m_dataPos], _size); 80 | m_dataPos += (int32_t)_size; 81 | return 1; 82 | } 83 | else 84 | { 85 | uint8_t* dst = (uint8_t*)_ptr; 86 | if (bytesLeft) 87 | { 88 | memcpy(dst, &m_data[m_dataPos], bytesLeft); 89 | m_dataPos += bytesLeft; 90 | } 91 | 92 | dst += bytesLeft; 93 | 94 | const int32_t remaining = (int32_t)_size - bytesLeft; 95 | 96 | if (m_dataPos == m_dataAvailable) 97 | { 98 | m_bytesRead += m_dataAvailable; 99 | if (!loadChunk()) 100 | return (remaining == 0) ? 1 : 0; 101 | m_dataPos = 0; 102 | } 103 | 104 | if (remaining > 0) 105 | { 106 | memcpy(dst, &m_data[m_dataPos], remaining); 107 | m_dataPos += remaining; 108 | } 109 | return 1; 110 | } 111 | } 112 | 113 | bool BinLoader::loadChunk() 114 | { 115 | uint32_t sig, size; 116 | size_t e = fread(&sig, sizeof(uint32_t), 1, m_file); 117 | if (e != 1) 118 | return false; 119 | 120 | if (!((sig == 0x23234646) || sig == Endian::swap(uint32_t(0x23234646)))) 121 | return false; 122 | 123 | e = fread(&size, sizeof(uint32_t), 1, m_file); 124 | if (e == 0) 125 | return false; 126 | 127 | if (sig == Endian::swap(uint32_t(0x23234646))) 128 | size = Endian::swap(size); 129 | 130 | if (m_srcDataSize < (int32_t)size) 131 | { 132 | delete[] m_srcData; 133 | m_srcData = new uint8_t[size]; 134 | m_srcDataSize = size; 135 | } 136 | 137 | e = fread(m_srcData, 1, size, m_file); 138 | 139 | if (e != size) 140 | return false; 141 | 142 | m_dataAvailable = -1; 143 | while (m_dataAvailable < 0) 144 | { 145 | m_dataAvailable = LZ4_decompress_safe((const char*)m_srcData, (char*)m_data, size, m_dataSize); 146 | if (m_dataAvailable < 0) 147 | { 148 | delete[] m_data; 149 | m_dataSize *= 2; 150 | m_data = new uint8_t[m_dataSize]; 151 | } 152 | } 153 | 154 | return true; 155 | } 156 | 157 | } // namespace rtm 158 | -------------------------------------------------------------------------------- /src/MTuner/src/loader/binloader.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_BINLOADER_H 7 | #define RTM_MTUNER_BINLOADER_H 8 | 9 | namespace rtm { 10 | 11 | class BinLoader 12 | { 13 | uint8_t* m_srcData; 14 | uint8_t* m_data; 15 | int32_t m_srcDataSize; 16 | int32_t m_dataSize; 17 | int32_t m_dataAvailable; 18 | int32_t m_dataPos; 19 | uint64_t m_bytesRead; 20 | FILE* m_file; 21 | bool m_compressed; 22 | 23 | public: 24 | BinLoader(FILE* _file, bool _compressed); 25 | ~BinLoader(); 26 | 27 | bool eof(); 28 | uint64_t tell(); 29 | uint64_t fileTell(); 30 | int read(void* _ptr, size_t _size); 31 | 32 | template 33 | int readVar(T& _var) 34 | { 35 | return read(&_var, sizeof(T)); 36 | } 37 | 38 | private: 39 | bool loadChunk(); 40 | }; 41 | 42 | } // namespace rtm 43 | 44 | #endif // RTM_MTUNER_BINLOADER_H 45 | -------------------------------------------------------------------------------- /src/MTuner/src/moduleswidget.cpp: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | ModulesWidget::ModulesWidget(QWidget* _parent, Qt::WindowFlags _flags) 11 | : QWidget(_parent, _flags) 12 | , m_currentItem(0) 13 | , m_currentInfo(0) 14 | { 15 | ui.setupUi(this); 16 | 17 | m_filter = findChild("lineEdit"); 18 | connect(m_filter, SIGNAL(textChanged(const QString&)), this, SLOT(filterChanged(const QString&))); 19 | 20 | m_list = findChild("treeWidget"); 21 | connect(m_list, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(itemClicked(QTreeWidgetItem*, int))); 22 | } 23 | 24 | void ModulesWidget::changeEvent(QEvent* _event) 25 | { 26 | QWidget::changeEvent(_event); 27 | if (_event->type() == QEvent::LanguageChange) 28 | ui.retranslateUi(this); 29 | } 30 | 31 | void ModulesWidget::setContext(CaptureContext* _context) 32 | { 33 | if (m_context == _context) 34 | return; 35 | 36 | m_context = _context; 37 | filterChanged(QString()); 38 | } 39 | 40 | void ModulesWidget::itemClicked(QTreeWidgetItem* _currentItem, int _column) 41 | { 42 | RTM_UNUSED(_column); 43 | if (!_currentItem) 44 | return; 45 | 46 | m_list->setFocus(); 47 | 48 | if (m_currentItem == _currentItem) 49 | { 50 | m_currentItem = 0; 51 | m_currentInfo = 0; 52 | m_list->setCurrentItem(0); 53 | emit moduleSelected(0); 54 | } 55 | else 56 | { 57 | m_currentItem = _currentItem; 58 | m_list->setCurrentItem(_currentItem); 59 | rdebug::ModuleInfo* info = (rdebug::ModuleInfo*)_currentItem->data(0,Qt::UserRole).toLongLong(); 60 | m_currentInfo = info; 61 | emit moduleSelected(info); 62 | } 63 | } 64 | 65 | void ModulesWidget::filterChanged(const QString& _text) 66 | { 67 | rdebug::ModuleInfo* info = m_currentInfo; 68 | 69 | if (m_context) 70 | { 71 | m_list->clear(); 72 | std::vector& modules = m_context->m_capture->getModuleInfos(); 73 | std::vector::reverse_iterator it = modules.rbegin(); 74 | std::vector::reverse_iterator end = modules.rend(); 75 | 76 | QLocale locale; 77 | QTreeWidgetItem* curItem = 0; 78 | while (it != end) 79 | { 80 | QString path = QString::fromUtf8(it->m_modulePath); 81 | 82 | if ((_text.length() == 0) || 83 | (path.indexOf(_text, 0, Qt::CaseInsensitive) >= 0)) 84 | { 85 | QString name = QString::fromUtf8(rtm::pathGetFileName(it->m_modulePath)); 86 | QTreeWidgetItem* item = new QTreeWidgetItem(QStringList() 87 | << name 88 | << ("0x" + QString::number(it->m_baseAddress, 16)) 89 | << ("0x" + QString::number(it->m_baseAddress + it->m_size, 16)) 90 | << locale.toString(it->m_size) 91 | << QString::fromUtf8(it->m_modulePath)); 92 | item->setData(0, Qt::UserRole, (qlonglong)&*it); 93 | item->setTextAlignment(3, Qt::AlignRight); 94 | 95 | if (&*it == info) 96 | curItem = item; 97 | 98 | m_list->addTopLevelItem(item); 99 | } 100 | ++it; 101 | } 102 | m_filter->setEnabled(true); 103 | m_list->setCurrentItem(curItem); 104 | 105 | if (_text.length() == 0) 106 | m_list->setFocus(); 107 | } 108 | else 109 | { 110 | m_list->clear(); 111 | m_filter->setEnabled(false); 112 | } 113 | } 114 | 115 | void ModulesWidget::setCurrentModule(rdebug::ModuleInfo* _module) 116 | { 117 | QTreeWidgetItemIterator it(m_list); 118 | while (*it) 119 | { 120 | if ((rdebug::ModuleInfo*)(*it)->data(0,Qt::UserRole).toULongLong() == _module) 121 | { 122 | (*it)->setSelected(true); 123 | return; 124 | } 125 | ++it; 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/MTuner/src/moduleswidget.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_MODULESWIDGET_H 7 | #define RTM_MTUNER_MODULESWIDGET_H 8 | 9 | #include 10 | 11 | struct CaptureContext; 12 | 13 | class ModulesWidget : public QWidget 14 | { 15 | Q_OBJECT 16 | 17 | private: 18 | QLineEdit* m_filter; 19 | QTreeWidget* m_list; 20 | QTreeWidgetItem* m_currentItem; 21 | CaptureContext* m_context; 22 | rdebug::ModuleInfo* m_currentInfo; 23 | 24 | public: 25 | ModulesWidget(QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 26 | 27 | void changeEvent(QEvent* _event); 28 | void setContext(CaptureContext* _capture); 29 | void setCurrentModule(rdebug::ModuleInfo* _module); 30 | 31 | public Q_SLOTS: 32 | void itemClicked(QTreeWidgetItem* _currentItem, int _column); 33 | void filterChanged(const QString&); 34 | 35 | Q_SIGNALS: 36 | void moduleSelected(void*); 37 | 38 | private: 39 | Ui::ModulesWidget ui; 40 | }; 41 | 42 | #endif // RTM_MTUNER_MODULESWIDGET_H 43 | -------------------------------------------------------------------------------- /src/MTuner/src/moduleswidget.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | ModulesWidget 4 | 5 | 6 | 7 | 0 8 | 0 9 | 659 10 | 489 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Filter: 23 | 24 | 25 | 26 | 27 | 28 | 29 | true 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | Qt::NoFocus 39 | 40 | 41 | QAbstractItemView::NoEditTriggers 42 | 43 | 44 | false 45 | 46 | 47 | QAbstractItemView::SingleSelection 48 | 49 | 50 | true 51 | 52 | 53 | 5 54 | 55 | 56 | 57 | Name 58 | 59 | 60 | 61 | 62 | Base Address 63 | 64 | 65 | 66 | 67 | End Address 68 | 69 | 70 | 71 | 72 | Size 73 | 74 | 75 | 76 | 77 | Path 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /src/MTuner/src/mtuner.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_MTUNER_H 7 | #define RTM_MTUNER_MTUNER_H 8 | 9 | #include 10 | #include 11 | 12 | class ProjectsManager; 13 | class SymbolStore; 14 | class HeapsWidget; 15 | class ModulesWidget; 16 | class HistogramWidget; 17 | class StackAndSource; 18 | class ExternalEditor; 19 | class CentralWidget; 20 | class SourceView; 21 | class Graph; 22 | class TagTreeWidget; 23 | class GCCSetup; 24 | 25 | class DockWidget : public QDockWidget 26 | { 27 | Q_OBJECT 28 | public: 29 | DockWidget(const QString& _title, QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0) 30 | : QDockWidget(_title, _parent, _flags) {} 31 | 32 | public Q_SLOTS: 33 | void toggleDock(bool) 34 | { 35 | setFloating(!isFloating()); 36 | } 37 | }; 38 | 39 | class ToolButtonHover : public QToolButton 40 | { 41 | Q_OBJECT 42 | QIcon m_default; 43 | QIcon m_hover; 44 | 45 | public: 46 | ToolButtonHover(QIcon _default, QIcon _hover, QWidget* _parent = 0) 47 | : QToolButton(_parent) 48 | , m_default(_default) 49 | , m_hover(_hover) 50 | { 51 | } 52 | 53 | void setDefaultAction(QAction* _action) { _action->setIcon(m_default); QToolButton::setDefaultAction(_action); } 54 | void leaveEvent(QEvent*) { defaultAction()->setIcon(m_default); } 55 | void enterEvent(QEnterEvent*) { defaultAction()->setIcon(m_hover); } 56 | }; 57 | 58 | class MTuner : public QMainWindow 59 | { 60 | Q_OBJECT 61 | 62 | private: 63 | ProjectsManager* m_projectsManager; 64 | QString m_watchedFile; 65 | QTimer* m_watchTimer; 66 | uint64_t m_capturePid; 67 | SymbolStore* m_symbolStore; 68 | GCCSetup* m_gccSetup; 69 | DockWidget* m_graphDock; 70 | DockWidget* m_statsDock; 71 | DockWidget* m_histogramDock; 72 | DockWidget* m_tagTreeDock; 73 | DockWidget* m_stackAndSourceDock; 74 | DockWidget* m_heapsDock; 75 | DockWidget* m_modulesDock; 76 | QProgressBar* m_loadingProgressBar; 77 | QLabel* m_statusBarRedDot; 78 | CentralWidget* m_centralWidget; 79 | QFileDialog* m_fileDialog; 80 | 81 | Graph* m_graph; 82 | HistogramWidget* m_histogramWidget; 83 | HeapsWidget* m_heapsWidget; 84 | ModulesWidget* m_modulesWidget; 85 | SourceView* m_sourceView; 86 | StackAndSource* m_stackAndSource; 87 | ExternalEditor* m_externalEditor; 88 | 89 | Stats* m_stats; 90 | bool m_showWelcomeDialog; 91 | bool m_closeStartPageWidgetOnOpen; 92 | 93 | TagTreeWidget* m_tagTree; 94 | 95 | public: 96 | MTuner(QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 97 | 98 | void show(); 99 | void setLoadingProgress(float _progress, const QString &_message); 100 | void changeEvent(QEvent* _event); 101 | void closeEvent(QCloseEvent* _event); 102 | void openFileFromPath(const QString& _file); 103 | bool handleFile(const QString& _file); 104 | 105 | public Q_SLOTS: 106 | 107 | // File 108 | void openFile(); 109 | void closeFile(); 110 | void openCaptureLocation(); 111 | QString getCaptureLocation(); 112 | void exit(); 113 | // Edit 114 | void manageProjects(); 115 | void setFilters(bool _filters); 116 | void setupGCCToolchains(); 117 | // Settings 118 | void setupSymbols(); 119 | void setupEditor(); 120 | void saveCaptureWindowLayout(); 121 | // Help 122 | void openDocumentation(); 123 | void about(); 124 | 125 | void heapSelected(uint64_t); 126 | void moduleSelected(void*); 127 | void graphModified(); 128 | void setWidgetSources(CaptureContext* _binView); 129 | 130 | void suicide(); 131 | void showHistogram(bool); 132 | void showGraph(bool); 133 | void showStats(bool); 134 | void showTagTree(bool); 135 | void showStackTrace(bool); 136 | void showHeaps(bool); 137 | void showModules(bool); 138 | 139 | void setStatusBarText(const QString&); 140 | void checkCaptureStatus(); 141 | void startCaptureStatusTimer(); 142 | void captureStarted(const QString&); 143 | void captureSetProcessID(uint64_t); 144 | 145 | void setFilteringState(bool,bool); 146 | 147 | QMenu* getLanguageParentMenu() { return ui.menuLanguage; } 148 | 149 | Q_SIGNALS: 150 | void binLoaded(bool); 151 | void setFilterState(bool); 152 | void setFilterButtonEnabled(bool); 153 | 154 | private: 155 | void showWelcomeDialog(); 156 | void setDockWindowIcon(DockWidget* _widget, const QString& _icon); 157 | void setupDockWindows(); 158 | void readSettings(); 159 | void writeSettings(); 160 | 161 | static uint32_t makeVersion(uint8_t _major, uint8_t _minor, uint8_t _detail); 162 | 163 | protected: 164 | void dragEnterEvent(QDragEnterEvent* _event); 165 | void dragMoveEvent(QDragMoveEvent* _event); 166 | void dragLeaveEvent(QDragLeaveEvent* _event); 167 | void dropEvent(QDropEvent* _event); 168 | 169 | private: 170 | Ui::MTunerClass ui; 171 | }; 172 | 173 | #endif // RTM_MTUNER_MTUNER_H 174 | -------------------------------------------------------------------------------- /src/MTuner/src/mtuner.qph: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Usage graph 5 | Графикон употребе меморије 6 | 7 | 8 | Statistics 9 | Статистике 10 | 11 | 12 | Histogram 13 | Хистограм 14 | 15 | 16 | Tag tree 17 | Стабло тагова 18 | 19 | 20 | Failed to load file! 21 | Неуспех приликом отварања фајла 22 | 23 | 24 | Select executable 25 | Изаберите извршни фајл 26 | 27 | 28 | Select working directory 29 | Изаберите радни директоријум 30 | 31 | 32 | Select local symbol store directory 33 | Изаберите локацију за локално складиштење симбола 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/MTuner/src/mtuner.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | ../resources/fonts/Maven Pro Bold.otf 4 | ../resources/fonts/Maven Pro Medium.otf 5 | ../resources/fonts/Maven Pro Regular.otf 6 | ../resources/images/Graph64.png 7 | ../resources/images/Graph128.png 8 | ../resources/images/Graph256.png 9 | ../resources/images/FlameSelected64.png 10 | ../resources/images/Open64.png 11 | ../resources/images/Symbol64.png 12 | ../resources/images/Flame64.png 13 | ../resources/images/Filter64.png 14 | ../resources/images/LeakSelected64.png 15 | ../resources/images/toolchain_android_arm.png 16 | ../resources/images/toolchain_android_mips.png 17 | ../resources/images/toolchain_android_x86.png 18 | ../resources/images/toolchain_ps3.png 19 | ../resources/images/toolchain_ps4.png 20 | ../resources/images/toolchain_ps5.png 21 | ../resources/images/toolchain_mingw.png 22 | ../resources/images/toolchain_switch.png 23 | ../resources/images/table.png 24 | ../resources/images/Documentation.png 25 | ../resources/images/Heaps.png 26 | ../resources/images/gnu64.png 27 | ../resources/images/notok.png 28 | ../resources/images/ok.png 29 | ../resources/images/red_dot.png 30 | ../resources/images/Editor64.png 31 | ../resources/images/StackTraceSource64.png 32 | ../resources/images/List64.png 33 | ../resources/images/ListSelected64.png 34 | ../resources/images/modules64.png 35 | ../resources/images/modules128.png 36 | ../resources/images/Run.png 37 | ../resources/images/TreeMapSelected64.png 38 | ../resources/images/Lupa16.png 39 | ../resources/images/StackTree64.png 40 | ../resources/images/StackTreeSelected64.png 41 | ../resources/images/Projects64.png 42 | ../resources/images/Leak64.png 43 | ../resources/images/Histogram64.png 44 | ../resources/images/Group64.png 45 | ../resources/images/TreeMap64.png 46 | ../resources/images/Icon64.png 47 | ../resources/images/GroupSelected64.png 48 | ../resources/images/Icon128.png 49 | ../resources/images/Icon256.png 50 | ../resources/images/linkedin.png 51 | ../resources/images/twitter.png 52 | ../resources/images/dock_close.png 53 | ../resources/images/dock_close_hover.png 54 | ../resources/images/dock_detach.png 55 | ../resources/images/dock_detach_hover.png 56 | ../resources/images/link64_active.png 57 | ../resources/images/link64_inactive.png 58 | 59 | 60 | -------------------------------------------------------------------------------- /src/MTuner/src/mtuner.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON DISCARDABLE "../resources/icons/Icon256.ico" 2 | -------------------------------------------------------------------------------- /src/MTuner/src/mtuner_de.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/src/mtuner_de.qm -------------------------------------------------------------------------------- /src/MTuner/src/mtuner_en.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/src/mtuner_en.qm -------------------------------------------------------------------------------- /src/MTuner/src/mtuner_it.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/src/mtuner_it.qm -------------------------------------------------------------------------------- /src/MTuner/src/mtuner_rs.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RudjiGames/MTuner/29b2e4cc3b8e8fc89bd1d1b54909cd52c70b26d7/src/MTuner/src/mtuner_rs.qm -------------------------------------------------------------------------------- /src/MTuner/src/mtunerlang.bat: -------------------------------------------------------------------------------- 1 | %QTDIR_VS2017_x64%\bin\lupdate.exe -verbose -no-obsolete mtunerlang.pro 2 | %QTDIR_VS2017_x64%\bin\linguist.exe mtuner_en.ts mtuner_rs.ts mtuner_it.ts mtuner_de.ts 3 | %QTDIR_VS2017_x64%\bin\lrelease mtunerlang.pro 4 | -------------------------------------------------------------------------------- /src/MTuner/src/operationsearch.cpp: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #include 7 | #include 8 | 9 | OperationSearch::OperationSearch(QWidget* _parent, Qt::WindowFlags _flags) : 10 | QWidget(_parent, _flags) 11 | { 12 | ui.setupUi(this); 13 | 14 | m_buttonPrev = findChild("buttonPrev"); 15 | m_buttonNext = findChild("buttonNext"); 16 | m_buttonSearch = findChild("buttonSearch"); 17 | m_address = findChild("lineEditAddress"); 18 | m_searchAddress = findChild("lineEditSearch"); 19 | m_searchType = findChild("comboBox"); 20 | m_leaksOnly = findChild("leaksCheckBox"); 21 | m_leaksOnly->setEnabled(false); 22 | m_leaksOnly->setVisible(false); 23 | 24 | m_searchAddress->setValidator(new QRegularExpressionValidator(QRegularExpression("0x?[0-9A-Fa-f]{1,16}"))); 25 | 26 | connect(m_buttonPrev, SIGNAL(clicked()), this, SIGNAL(findPrev())); 27 | connect(m_buttonNext, SIGNAL(clicked()), this, SIGNAL(findNext())); 28 | connect(m_searchAddress, SIGNAL(textChanged(const QString&)), this, SLOT(searchStringChanged(const QString&))); 29 | connect(m_buttonSearch, SIGNAL(clicked()), this, SLOT(search())); 30 | connect(m_searchType, SIGNAL(activated(int)), this, SLOT(searchTypeChanged(int))); 31 | connect(m_leaksOnly, SIGNAL(stateChanged(int)), this, SLOT(leaksOnlyChanged(int))); 32 | } 33 | 34 | void OperationSearch::changeEvent(QEvent* _event) 35 | { 36 | QWidget::changeEvent(_event); 37 | if (_event->type() == QEvent::LanguageChange) 38 | ui.retranslateUi(this); 39 | } 40 | 41 | void OperationSearch::setPrevEnabled(bool _enabled) 42 | { 43 | m_buttonPrev->setEnabled(_enabled); 44 | } 45 | 46 | void OperationSearch::setNextEnabled(bool _enabled) 47 | { 48 | m_buttonNext->setEnabled(_enabled); 49 | } 50 | 51 | void OperationSearch::setAddress(uint64_t _address) 52 | { 53 | QString hex = QString::number(_address,16); 54 | int hexLen = hex.length(); 55 | int zeroes = 0; 56 | if (hexLen <= 8) 57 | zeroes = 8-hexLen; 58 | else 59 | zeroes = 16-hexLen; 60 | 61 | while (zeroes--) 62 | hex = "0" + hex; 63 | 64 | hex = "0x" + hex; 65 | m_address->setText(hex); 66 | m_address->setEnabled(true); 67 | } 68 | 69 | void OperationSearch::search() 70 | { 71 | if (m_searchType->currentIndex()==0) 72 | { 73 | uint64_t address = m_searchAddress->text().toULongLong(0,16); 74 | emit searchByAddress(address); 75 | } 76 | else 77 | { 78 | uint64_t size = m_searchAddress->text().toULongLong(0,10); 79 | emit searchBySize(size); 80 | } 81 | } 82 | 83 | void OperationSearch::searchTypeChanged(int _type) 84 | { 85 | if (_type==0) 86 | m_searchAddress->setValidator(new QRegularExpressionValidator(QRegularExpression("0x?[0-9A-Fa-f]{1,16}"))); 87 | else 88 | m_searchAddress->setValidator(new QRegularExpressionValidator(QRegularExpression("[0-9]{1,16}"))); 89 | m_searchAddress->setText(""); 90 | } 91 | 92 | void OperationSearch::searchStringChanged(const QString& _text) 93 | { 94 | m_buttonSearch->setEnabled(_text.length()!=0); 95 | } 96 | 97 | void OperationSearch::leaksOnlyChanged(int) 98 | { 99 | emit showLeaksOnly(m_leaksOnly->isChecked()); 100 | } 101 | -------------------------------------------------------------------------------- /src/MTuner/src/operationsearch.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_OPERATIONSEARCH_H 7 | #define RTM_MTUNER_OPERATIONSEARCH_H 8 | 9 | #include 10 | 11 | class OperationSearch : public QWidget 12 | { 13 | Q_OBJECT 14 | 15 | QPushButton* m_buttonPrev; 16 | QPushButton* m_buttonNext; 17 | QToolButton* m_buttonSearch; 18 | QLineEdit* m_address; 19 | QLineEdit* m_searchAddress; 20 | QComboBox* m_searchType; 21 | QCheckBox* m_leaksOnly; 22 | 23 | public: 24 | OperationSearch(QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 25 | 26 | bool isLeaksOnlyChecked() const { return m_leaksOnly->isChecked(); } 27 | void changeEvent(QEvent* _event); 28 | void setPrevEnabled(bool); 29 | void setNextEnabled(bool); 30 | void setAddress(uint64_t _address); 31 | 32 | Q_SIGNALS: 33 | void searchByAddress(uint64_t); 34 | void searchBySize(uint64_t); 35 | void findPrev(); 36 | void findNext(); 37 | void showLeaksOnly(bool); 38 | 39 | public Q_SLOTS: 40 | void search(); 41 | void searchTypeChanged(int); 42 | void searchStringChanged(const QString&); 43 | void leaksOnlyChanged(int); 44 | 45 | private: 46 | Ui::OperationSearchWidget ui; 47 | }; 48 | 49 | #endif // RTM_MTUNER_OPERATIONSEARCH_H 50 | -------------------------------------------------------------------------------- /src/MTuner/src/operationslist.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_OPERATIONSLIST_H 7 | #define RTM_MTUNER_OPERATIONSLIST_H 8 | 9 | #include 10 | 11 | struct CaptureContext; 12 | class OperationTableSource; 13 | 14 | class OperationsList : public QWidget 15 | { 16 | Q_OBJECT 17 | 18 | private: 19 | CaptureContext* m_context; 20 | BigTable* m_operationList; 21 | OperationSearch* m_operationSearch; 22 | OperationTableSource* m_tableSource; 23 | rtm::MemoryOperation* m_currentItem; 24 | bool m_enableFiltering; 25 | 26 | int m_savedColumn; 27 | Qt::SortOrder m_savedOrder; 28 | QByteArray m_headerState; 29 | QString m_settingsGroupName; 30 | 31 | public: 32 | OperationsList(QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 33 | ~OperationsList(); 34 | 35 | bool isLeaksOnlyChecked() const { return m_operationSearch->isLeaksOnlyChecked(); } 36 | void changeEvent(QEvent* _event); 37 | void setContext(CaptureContext* _context, bool _valid = false); 38 | void setFilteringState(bool _state, bool _leaksOnly); 39 | bool getFilteringState() const; 40 | void setSearchVisible(bool _visible) { m_operationSearch->setVisible(_visible); } 41 | void loadState(QSettings& _settings, const QString& _name, bool _resetGeometry); 42 | void saveState(QSettings& _settings); 43 | 44 | Q_SIGNALS: 45 | void setStackTrace(rtm::StackTrace**, int); 46 | void highlightTime(uint64_t); 47 | 48 | public Q_SLOTS: 49 | void selectionChanged(void*); 50 | void selectPrevious(); 51 | void selectNext(); 52 | void selectNextByAddress(uint64_t); 53 | void selectNextBySize(uint64_t); 54 | void toggleLeaksOnly(bool); 55 | 56 | private: 57 | Ui::OperationsListWidget ui; 58 | }; 59 | 60 | #endif // RTM_MTUNER_OPERATIONSLIST_H 61 | -------------------------------------------------------------------------------- /src/MTuner/src/operationslist.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | OperationsListWidget 4 | 5 | 6 | 7 | 0 8 | 0 9 | 1211 10 | 798 11 | 12 | 13 | 14 | Operations 15 | 16 | 17 | 18 | 0 19 | 20 | 21 | 0 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | BigTable 34 | QWidget 35 |
../src/bigtable.h
36 | 1 37 |
38 | 39 | OperationSearch 40 | QWidget 41 |
../src/operationsearch.h
42 | 1 43 |
44 |
45 | 46 | 47 |
48 | -------------------------------------------------------------------------------- /src/MTuner/src/progressbar.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | ProgressBar 4 | 5 | 6 | 7 | 0 8 | 0 9 | 491 10 | 28 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 0 19 | 20 | 21 | 0 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/MTuner/src/projectsmanager.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_PROJECTSMANAGER_H 7 | #define RTM_MTUNER_PROJECTSMANAGER_H 8 | 9 | #include 10 | #include 11 | 12 | struct Project 13 | { 14 | QString m_executablePath; 15 | QString m_cmdArgs; 16 | QString m_workingDir; 17 | QStringList m_environment; 18 | bool m_inheritEnv; 19 | 20 | Project() 21 | : m_inheritEnv(true) 22 | { 23 | } 24 | 25 | bool operator == (const Project& _other) 26 | { 27 | return !(*this != _other); 28 | } 29 | 30 | bool operator != (const Project& _other) 31 | { 32 | return ((m_executablePath != _other.m_executablePath) || 33 | (m_cmdArgs != _other.m_cmdArgs) || 34 | (m_workingDir != _other.m_workingDir) || 35 | (m_environment != _other.m_environment) || 36 | (m_inheritEnv != _other.m_inheritEnv)); 37 | } 38 | }; 39 | 40 | class ProjectsManager : public QDialog 41 | { 42 | Q_OBJECT 43 | 44 | public: 45 | QVector m_savedProjects; 46 | QVector m_projects; 47 | bool m_projectListModified; 48 | QLineEdit* m_txtExecutable; 49 | QLineEdit* m_txtCommandLine; 50 | QLineEdit* m_txtWorkingDir; 51 | QTreeWidget* m_listProjects; 52 | QPushButton* m_buttonAdd; 53 | QPushButton* m_buttonRemove; 54 | QPushButton* m_buttonRun; 55 | QFileSystemWatcher* m_watcher; 56 | bool m_injecting; 57 | QString m_currentCaptureFile; 58 | QStringList m_currentEnvironment; 59 | 60 | public: 61 | ProjectsManager(QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 62 | 63 | void save(); 64 | void changeEvent(QEvent* _event); 65 | void addProject(const Project& _project) { m_projects.push_back(_project); updateProjectList(); } 66 | int getNumProjects() const { return m_projects.size(); } 67 | const Project& getProject(int _index) const { return m_projects[_index]; } 68 | bool run(const QString& _executable, const QString& _cmd = QString(), const QString& _workingDir = QString(), const QStringList& _environment = QStringList(), bool _inheritEnv = true, int _allocator = 0, bool _shouldCapture = true, bool _shouldLoad = true); 69 | void loadSettings(QSettings& _settings); 70 | void saveSettings(QSettings& _settings); 71 | 72 | public Q_SLOTS: 73 | void buttonAdd(); 74 | void buttonRemove(); 75 | void buttonRun(); 76 | void textParamsChanged(); 77 | void projectSelectionChanged(); 78 | void browseExecutable(); 79 | void browseWorkingDir(); 80 | void editEnvironment(); 81 | void dirChanged(const QString&); 82 | void inheritEnv(bool); 83 | void restore(); 84 | void processInjectFinished(int _exitCode, QProcess::ExitStatus _status); 85 | bool isInjecting(); 86 | 87 | Q_SIGNALS: 88 | void captureCreated(const QString& _path); 89 | void captureSetProcessID(uint64_t _pid); 90 | void captureStartMonitoring(); 91 | 92 | private: 93 | void updateProjectList(); 94 | bool isExecutablePathValid(); 95 | bool projectExists(); 96 | bool isWorkingDirectoryValid(); 97 | 98 | protected: 99 | void dragEnterEvent(QDragEnterEvent* _event); 100 | void dragMoveEvent(QDragMoveEvent* _event); 101 | void dragLeaveEvent(QDragLeaveEvent* _event); 102 | void dropEvent(QDropEvent* _event); 103 | void reject(); // QDialog 104 | 105 | private: 106 | Ui::ProjectsDialog ui; 107 | }; 108 | 109 | #endif // RTM_MTUNER_PROJECTSMANAGER_H 110 | -------------------------------------------------------------------------------- /src/MTuner/src/sourceview.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_SOURCEVIEW_H 7 | #define RTM_MTUNER_SOURCEVIEW_H 8 | 9 | #include 10 | 11 | class ExternalEditor; 12 | struct CaptureContext; 13 | 14 | class SourceView : public QPlainTextEdit 15 | { 16 | Q_OBJECT 17 | 18 | QString m_currentFile; 19 | int m_currentLine; 20 | QMenu* m_contextMenu; 21 | QAction* m_tabWidthAction4; 22 | QAction* m_tabWidthAction8; 23 | QAction* m_openInEditorAction; 24 | ExternalEditor* m_editorDialog; 25 | CaptureContext* m_context; 26 | 27 | public: 28 | SourceView(QWidget* _parent = 0); 29 | 30 | void changeEvent(QEvent* _event); 31 | void lineNumberAreaPaintEvent(QPaintEvent* _event); 32 | int lineNumberAreaWidth(); 33 | void setTabWidth(int _width); 34 | void setEditorDialog(ExternalEditor* _editor) { m_editorDialog = _editor; } 35 | void setContext(CaptureContext* _context) { m_context = _context; } 36 | 37 | protected: 38 | void contextMenuEvent(QContextMenuEvent* _event); 39 | void resizeEvent(QResizeEvent* _event); 40 | void createCustomContextMenu(); 41 | 42 | private Q_SLOTS: 43 | void updateLineNumberAreaWidth(int _newBlockCount); 44 | void highlightCurrentLine(); 45 | void updateLineNumberArea(const QRect&, int); 46 | void openFile(const QString& _file, int _row, int _column); 47 | void setTabWidthTo4(); 48 | void setTabWidthTo8(); 49 | void openInEditor(); 50 | 51 | private: 52 | QWidget *lineNumberArea; 53 | }; 54 | 55 | class LineNumberArea : public QWidget 56 | { 57 | private: 58 | SourceView* m_sourceView; 59 | 60 | public: 61 | LineNumberArea(SourceView* _editor) : 62 | QWidget(_editor) 63 | { 64 | m_sourceView = _editor; 65 | } 66 | 67 | QSize sizeHint() const 68 | { 69 | return QSize(m_sourceView->lineNumberAreaWidth(), 0); 70 | } 71 | 72 | protected: 73 | void paintEvent(QPaintEvent* _event) 74 | { 75 | m_sourceView->lineNumberAreaPaintEvent(_event); 76 | } 77 | }; 78 | 79 | #endif // RTM_MTUNER_SOURCEVIEW_H 80 | -------------------------------------------------------------------------------- /src/MTuner/src/stackandsource.cpp: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #include 7 | #include 8 | 9 | StackAndSource::StackAndSource(ExternalEditor* _editorDlg, QWidget* _parent, Qt::WindowFlags _flags) : 10 | QWidget(_parent, _flags), 11 | m_editorDialog(_editorDlg) 12 | { 13 | ui.setupUi(this); 14 | 15 | m_source = findChild("sourceViewWidget"); 16 | m_source->setEditorDialog(m_editorDialog); 17 | m_stackTrace = findChild("stackTraceWidget"); 18 | m_fileName = findChild("fileName"); 19 | 20 | connect(m_stackTrace, SIGNAL(openFile(const QString&,int,int)), m_source, SLOT(openFile(const QString&,int,int))); 21 | connect(m_stackTrace, SIGNAL(openFile(const QString&,int,int)), this, SLOT(setFileName(const QString&,int,int))); 22 | } 23 | 24 | void StackAndSource::changeEvent(QEvent* _event) 25 | { 26 | QWidget::changeEvent(_event); 27 | if (_event->type() == QEvent::LanguageChange) 28 | ui.retranslateUi(this); 29 | } 30 | 31 | void StackAndSource::setContext(CaptureContext* _context) 32 | { 33 | m_source->setContext(_context); 34 | m_stackTrace->setContext(_context); 35 | } 36 | 37 | void StackAndSource::setStackTrace(rtm::StackTrace** _trace, int _num) 38 | { 39 | m_stackTrace->setStackTrace(_trace, _num); 40 | } 41 | 42 | void StackAndSource::setFileName(const QString& _file, int, int) 43 | { 44 | if (_file != QString("Unknown")) 45 | m_fileName->setText(QString("") + _file + QString("")); 46 | else 47 | m_fileName->setText(""); 48 | } 49 | -------------------------------------------------------------------------------- /src/MTuner/src/stackandsource.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_STACKANDSOURCE_H 7 | #define RTM_MTUNER_STACKANDSOURCE_H 8 | 9 | #include 10 | 11 | class ExternalEditor; 12 | 13 | class StackAndSource : public QWidget 14 | { 15 | Q_OBJECT 16 | 17 | StackTrace* m_stackTrace; 18 | SourceView* m_source; 19 | ExternalEditor* m_editorDialog; 20 | QLabel* m_fileName; 21 | 22 | public: 23 | StackAndSource(ExternalEditor* inEditorDlg, QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 24 | 25 | void changeEvent(QEvent* _event); 26 | StackTrace* getStackTrace() { return m_stackTrace; } 27 | 28 | public Q_SLOTS: 29 | void setContext(CaptureContext*); 30 | void setStackTrace(rtm::StackTrace**, int); 31 | void setFileName(const QString&, int, int); 32 | 33 | private: 34 | Ui::StackAndSource ui; 35 | }; 36 | 37 | #endif // RTM_MTUNER_STACKANDSOURCE_H 38 | -------------------------------------------------------------------------------- /src/MTuner/src/stackandsource.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | StackAndSource 4 | 5 | 6 | 7 | 0 8 | 0 9 | 453 10 | 829 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 0 19 | 20 | 21 | 0 22 | 23 | 24 | 0 25 | 26 | 27 | 0 28 | 29 | 30 | 0 31 | 32 | 33 | 34 | 35 | Qt::Vertical 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | QFrame::Sunken 44 | 45 | 46 | 3 47 | 48 | 49 | Qt::Horizontal 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | Qt::RichText 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 300 68 | 0 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | StackTrace 82 | QWidget 83 |
../src/stacktrace.h
84 | 1 85 |
86 | 87 | SourceView 88 | QWidget 89 |
../src/sourceview.h
90 | 1 91 |
92 |
93 | 94 | 95 |
96 | -------------------------------------------------------------------------------- /src/MTuner/src/stacktrace.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_STACKTRACE_H 7 | #define RTM_MTUNER_STACKTRACE_H 8 | 9 | #include 10 | 11 | class QSpinBox; 12 | class StackTrace; 13 | struct CaptureContext; 14 | 15 | class QToolTipper : public QObject 16 | { 17 | Q_OBJECT 18 | 19 | StackTrace* m_stackTrace; 20 | 21 | public: 22 | explicit QToolTipper(QObject* parent = NULL, StackTrace* _trace = 0) 23 | : QObject(parent) 24 | , m_stackTrace(_trace) 25 | {} 26 | 27 | protected: 28 | bool eventFilter(QObject* obj, QEvent* event); 29 | }; 30 | 31 | class StackTrace : public QWidget 32 | { 33 | Q_OBJECT 34 | 35 | private: 36 | QLabel* m_toolTipLabel; 37 | rtm::StackTrace** m_currentTrace; 38 | uint32_t m_currentTraceCnt; 39 | uint32_t m_currentTraceIdx; 40 | QTableWidget* m_table; 41 | QMenu* m_contextMenu; 42 | QAction* m_actionCopy; 43 | QAction* m_actionCopyAll; 44 | int m_copyIndex; 45 | QToolButton* m_buttonDec; 46 | QToolButton* m_buttonInc; 47 | QSpinBox* m_spinBox; 48 | QLabel* m_totalTraces; 49 | CaptureContext* m_context; 50 | rtm::StackTrace* m_stackTrace; 51 | QString m_selectedFunc; 52 | QString m_settingsGroupName; 53 | 54 | public: 55 | StackTrace(QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 56 | 57 | void leaveEvent(QEvent*) { m_toolTipLabel->hide(); } 58 | void changeEvent(QEvent* _event); 59 | void contextMenuEvent(QContextMenuEvent* _event); 60 | void setContext(CaptureContext* _context); 61 | void clear(); 62 | void updateView(); 63 | void loadState(QSettings& _settings, const QString& _name, bool _resetGeometry); 64 | void saveState(QSettings& _settings); 65 | void showToolTip(const QPoint& _pos, const QString& _itemTooltip); 66 | void hideToolTip(); 67 | 68 | public Q_SLOTS: 69 | void currentCellChanged(int _currentRow, int _currentColumn, int _previousRow, int _previousColumn); 70 | void setStackTrace(rtm::StackTrace** _stackTrace, int); 71 | void incPressed(); 72 | void decPressed(); 73 | void copy(); 74 | void copyAll(); 75 | void copyResetIndex(); 76 | 77 | Q_SIGNALS: 78 | void openFile(const QString& _file, int _row, int _column); 79 | 80 | private: 81 | void setCount(uint32_t _cnt); 82 | Ui::StackTrace ui; 83 | }; 84 | 85 | #endif // RTM_MTUNER_STACKTRACE_H 86 | -------------------------------------------------------------------------------- /src/MTuner/src/stacktree.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | stackTree 4 | 5 | 6 | 7 | 0 8 | 0 9 | 1032 10 | 660 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 0 19 | 20 | 21 | 0 22 | 23 | 24 | 0 25 | 26 | 27 | 0 28 | 29 | 30 | 31 | 32 | QAbstractItemView::NoEditTriggers 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/MTuner/src/stacktreewidget.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_STACKTREEWIDGET_H 7 | #define RTM_MTUNER_STACKTREEWIDGET_H 8 | 9 | #include 10 | 11 | class TreeItem; 12 | struct CaptureContext; 13 | 14 | class TreeModel : public QAbstractItemModel 15 | { 16 | Q_OBJECT 17 | 18 | private: 19 | CaptureContext* m_context; 20 | TreeItem* m_rootItem; 21 | 22 | public: 23 | int m_savedColumn; 24 | Qt::SortOrder m_savedOrder; 25 | 26 | TreeModel(CaptureContext* _context, QObject* _parent = 0); 27 | ~TreeModel(); 28 | 29 | QVariant data(const QModelIndex& _index, int _role) const; 30 | Qt::ItemFlags flags(const QModelIndex& _index) const; 31 | QVariant headerData(int _section, Qt::Orientation _orientation, int _role = Qt::DisplayRole) const; 32 | QModelIndex index(int _row, int _column, const QModelIndex& _parent = QModelIndex()) const; 33 | QModelIndex parent(const QModelIndex& _index) const; 34 | int rowCount(const QModelIndex& _parent = QModelIndex()) const; 35 | int columnCount(const QModelIndex& _parent = QModelIndex()) const; 36 | void sort(int _column, Qt::SortOrder _order); 37 | void updateData(); 38 | 39 | private: 40 | void setupModelData(const rtm::StackTraceTree& _tree, TreeItem* _parent,const rtm::StackTraceTree* _root, int _depth); 41 | }; 42 | 43 | class ProgressBarDelegate : public QStyledItemDelegate 44 | { 45 | Q_OBJECT 46 | 47 | public: 48 | ProgressBarDelegate(QWidget* _parent = 0) : 49 | QStyledItemDelegate(_parent) 50 | {} 51 | 52 | void paint(QPainter* _painter, const QStyleOptionViewItem& _option, const QModelIndex& _index) const; 53 | QSize sizeHint(const QStyleOptionViewItem& _option, const QModelIndex& _index) const; 54 | }; 55 | 56 | class StackTreeWidget : public QWidget 57 | { 58 | Q_OBJECT 59 | 60 | std::vector m_stackTraces; 61 | bool m_headerStateRestored; 62 | CaptureContext* m_context; 63 | QTreeView* m_tree; 64 | bool m_enableFiltering; 65 | 66 | int m_savedColumn; 67 | Qt::SortOrder m_savedOrder; 68 | QString m_settingsGroupName; 69 | 70 | public: 71 | StackTreeWidget(QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 72 | virtual ~StackTreeWidget(); 73 | 74 | void changeEvent(QEvent* _event); 75 | void loadState(QSettings& _settings, const QString& _name, bool _resetGeometry); 76 | void saveState(QSettings& _settings); 77 | void setContext(CaptureContext* _context); 78 | void setFilteringState(bool _state); 79 | bool getFilteringState() const; 80 | void setupTree(); 81 | 82 | public Q_SLOTS: 83 | void rowClicked(const QModelIndex&); 84 | 85 | Q_SIGNALS: 86 | void setStackTrace(rtm::StackTrace**, int); 87 | 88 | private: 89 | Ui::stackTree ui; 90 | }; 91 | 92 | #endif // RTM_MTUNER_STACKTREEWIDGET_H 93 | -------------------------------------------------------------------------------- /src/MTuner/src/startpage.cpp: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | static QString getMessage(const QString& _string) 11 | { 12 | return QString("

") + 13 | _string + QString("

"); 14 | } 15 | 16 | StartPageWidget::StartPageWidget(QWidget* _parent, Qt::WindowFlags _flags) : 17 | QWidget(_parent, _flags) 18 | { 19 | ui.setupUi(this); 20 | ui.label_version->setText(getMessage(QString("v") + QString(MTunerVersion))); 21 | } 22 | 23 | void StartPageWidget::changeEvent(QEvent* _event) 24 | { 25 | QWidget::changeEvent(_event); 26 | if (_event->type() == QEvent::LanguageChange) 27 | ui.retranslateUi(this); 28 | } 29 | -------------------------------------------------------------------------------- /src/MTuner/src/startpage.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_STARTPAGEWIDGET_H 7 | #define RTM_MTUNER_STARTPAGEWIDGET_H 8 | 9 | #include 10 | 11 | class StartPageWidget : public QWidget 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | StartPageWidget(QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 17 | 18 | void changeEvent(QEvent* _event); 19 | 20 | private: 21 | Ui::StartPageWidget ui; 22 | }; 23 | 24 | #endif // RTM_MTUNER_STARTPAGEWIDGET_H 25 | -------------------------------------------------------------------------------- /src/MTuner/src/stats.cpp: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | Stats::Stats(QWidget* _parent, Qt::WindowFlags _flags) : 11 | QWidget(_parent, _flags) 12 | { 13 | ui.setupUi(this); 14 | m_context = nullptr; 15 | 16 | m_table = findChild("tableWidget"); 17 | m_table->setGridStyle(Qt::NoPen); 18 | m_table->setItemDelegate( new StatsDelegate() ); 19 | m_table->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); 20 | m_table->horizontalHeader()->setHighlightSections(true); 21 | } 22 | 23 | void Stats::changeEvent(QEvent* _event) 24 | { 25 | QWidget::changeEvent(_event); 26 | if (_event->type() == QEvent::LanguageChange) 27 | ui.retranslateUi(this); 28 | } 29 | 30 | void Stats::setContext(CaptureContext* _context) 31 | { 32 | m_context = _context; 33 | updateUI(); 34 | } 35 | 36 | void Stats::updateUI() 37 | { 38 | if (!m_context) 39 | { 40 | clear(); 41 | return; 42 | } 43 | 44 | QLocale locale; 45 | 46 | const rtm::MemoryStats& globalStats = m_context->m_capture->getGlobalStats(); 47 | 48 | m_table->item(0,0)->setText(locale.toString(qulonglong(globalStats.m_memoryUsage))); 49 | m_table->item(1,0)->setText(locale.toString(qulonglong(globalStats.m_memoryUsagePeak))); 50 | m_table->item(2,0)->setText(locale.toString(globalStats.m_numberOfOperations)); 51 | m_table->item(3,0)->setText(locale.toString(globalStats.m_numberOfAllocations)); 52 | m_table->item(4,0)->setText(locale.toString(globalStats.m_numberOfReAllocations)); 53 | m_table->item(5,0)->setText(locale.toString(globalStats.m_numberOfFrees)); 54 | m_table->item(6,0)->setText(locale.toString(globalStats.m_numberOfLiveBlocks)); 55 | m_table->item(7,0)->setText(locale.toString(globalStats.m_overhead)); 56 | m_table->item(8,0)->setText(locale.toString(globalStats.m_overheadPeak)); 57 | 58 | const rtm::MemoryStats& snapshotStats = m_context->m_capture->getSnapshotStats(); 59 | 60 | m_table->item(0,1)->setText(locale.toString(qulonglong(snapshotStats.m_memoryUsage))); 61 | m_table->item(1,1)->setText(locale.toString(qulonglong(snapshotStats.m_memoryUsagePeak))); 62 | m_table->item(2,1)->setText(locale.toString(snapshotStats.m_numberOfOperations)); 63 | m_table->item(3,1)->setText(locale.toString(snapshotStats.m_numberOfAllocations)); 64 | m_table->item(4,1)->setText(locale.toString(snapshotStats.m_numberOfReAllocations)); 65 | m_table->item(5,1)->setText(locale.toString(snapshotStats.m_numberOfFrees)); 66 | m_table->item(6,1)->setText(locale.toString(snapshotStats.m_numberOfLiveBlocks)); 67 | m_table->item(7,1)->setText(locale.toString(snapshotStats.m_overhead)); 68 | m_table->item(8,1)->setText(locale.toString(snapshotStats.m_overheadPeak)); 69 | } 70 | 71 | void Stats::clear() 72 | { 73 | for (uint32_t i=0; i<9; ++i) 74 | for (uint32_t j=0; j<2; j++) 75 | m_table->item(i,j)->setText(""); 76 | } 77 | -------------------------------------------------------------------------------- /src/MTuner/src/stats.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_STATS_H 7 | #define RTM_MTUNER_STATS_H 8 | 9 | #include 10 | 11 | class QTableWidget; 12 | struct CaptureContext; 13 | 14 | /// Disable focus selection on table 15 | class StatsDelegate : public QItemDelegate 16 | { 17 | Q_OBJECT 18 | public: 19 | virtual void drawFocus(QPainter*,const QStyleOptionViewItem&,const QRect&) const {} 20 | }; 21 | 22 | class Stats : public QWidget 23 | { 24 | Q_OBJECT 25 | 26 | private: 27 | QTableWidget* m_table; 28 | CaptureContext* m_context; 29 | 30 | public: 31 | Stats(QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 32 | 33 | void changeEvent(QEvent* event); 34 | void setContext(CaptureContext* _context); 35 | void clear(); 36 | 37 | public Q_SLOTS: 38 | void updateUI(); 39 | 40 | private: 41 | Ui::Stats ui; 42 | }; 43 | 44 | #endif // RTM_MTUNER_STATS_H 45 | -------------------------------------------------------------------------------- /src/MTuner/src/symbolstore.cpp: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #include 7 | #include 8 | 9 | #if RTM_PLATFORM_WINDOWS 10 | #define WIN32_LEAN_AND_MEAN 11 | #include 12 | #endif 13 | 14 | SymbolStore::SymbolStore(QWidget* _parent, Qt::WindowFlags _flags) 15 | : QDialog(_parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint) 16 | { 17 | RTM_UNUSED(_flags); 18 | ui.setupUi(this); 19 | 20 | m_publicStore = findChild("textPublicStore"); 21 | m_localStore = findChild("textLocalStore"); 22 | m_srcRegistry = findChild("checkRegistry"); 23 | m_buttonDefault = findChild("buttonDefault"); 24 | m_buttonBrowse = findChild("buttonBrowse"); 25 | 26 | m_srcRegistry->setChecked(false); 27 | 28 | #if RTM_PLATFORM_WINDOWS 29 | wchar_t buffer[4096]; 30 | bool enableRegistry = GetEnvironmentVariableW(L"_NT_SYMBOL_PATH", (LPWSTR)buffer, sizeof(buffer)) > 0; 31 | m_hasRegistryEntry = enableRegistry; 32 | m_srcRegistry->setEnabled(enableRegistry); 33 | #else 34 | m_srcRegistry->setEnabled(false); 35 | #endif 36 | } 37 | 38 | void SymbolStore::changeEvent(QEvent* _event) 39 | { 40 | QDialog::changeEvent(_event); 41 | if (_event->type() == QEvent::LanguageChange) 42 | ui.retranslateUi(this); 43 | } 44 | 45 | QString SymbolStore::getSymbolStoreString() const 46 | { 47 | QString ret(""); 48 | 49 | if (m_srcRegistry->isChecked()) 50 | { 51 | #if RTM_PLATFORM_WINDOWS 52 | wchar_t buffer[4096]; 53 | GetEnvironmentVariableW(L"_NT_SYMBOL_PATH", (LPWSTR)buffer, sizeof(buffer)); 54 | ret = QString::fromWCharArray(buffer); 55 | #endif 56 | } 57 | 58 | // http server need a local cache folder to store the symbol 59 | if (m_publicStore->text().contains(QRegularExpression("https?://"))) 60 | { 61 | if (ret.length()) 62 | ret = ret + QString(";"); 63 | 64 | ret = ret + QString("SRV*"); 65 | if (!m_localStore->text().isEmpty()) 66 | { 67 | ret = ret + m_localStore->text(); 68 | } 69 | else 70 | ret = ret + QDir::toNativeSeparators(QDir::temp().absoluteFilePath("symbolcache")); 71 | 72 | ret = ret + QString("*"); 73 | ret = ret + m_publicStore->text(); 74 | } 75 | 76 | return ret; 77 | } 78 | 79 | QString SymbolStore::getLocalStore() const 80 | { 81 | return m_localStore->text(); 82 | } 83 | 84 | void SymbolStore::setLocalStore(const QString& _localStore) 85 | { 86 | m_localStore->setText(_localStore); 87 | } 88 | 89 | QString SymbolStore::getPublicStore() const 90 | { 91 | return m_publicStore->text(); 92 | } 93 | 94 | void SymbolStore::setPublicStore(const QString& _publicStore) 95 | { 96 | m_publicStore->setText(_publicStore); 97 | } 98 | 99 | bool SymbolStore::isRegistryChecked() const 100 | { 101 | return m_srcRegistry->isChecked(); 102 | } 103 | 104 | void SymbolStore::setChecked(bool _registry) 105 | { 106 | if (m_hasRegistryEntry && _registry) 107 | m_srcRegistry->setChecked(_registry); 108 | } 109 | 110 | void SymbolStore::save() 111 | { 112 | m_restoreRegistryChecked = m_srcRegistry->isChecked(); 113 | m_restorePublicStore = m_publicStore->text(); 114 | m_restoreLocalStore = m_localStore->text(); 115 | } 116 | 117 | void SymbolStore::selectLocalStore() 118 | { 119 | QString dir = QFileDialog::getExistingDirectory(this, tr("select local symbol store directory"), 120 | "", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); 121 | 122 | if (!dir.isEmpty()) 123 | m_localStore->setText(QDir::toNativeSeparators(dir)); 124 | } 125 | 126 | void SymbolStore::defaultSymbolServer() 127 | { 128 | m_publicStore->setText("https://msdl.microsoft.com/download/symbols"); 129 | } 130 | 131 | void SymbolStore::visitMSDN() 132 | { 133 | QDesktopServices::openUrl(QUrl("https://msdn.microsoft.com/en-us/library/ff537994(v=vs.85).aspx", QUrl::TolerantMode)); 134 | } 135 | 136 | int SymbolStore::exec() 137 | { 138 | show(); 139 | setFixedHeight(height()); 140 | return QDialog::exec(); 141 | } 142 | 143 | void SymbolStore::accept() 144 | { 145 | QDialog::accept(); 146 | } 147 | 148 | void SymbolStore::reject() 149 | { 150 | m_srcRegistry->setChecked(m_restoreRegistryChecked); 151 | m_publicStore->setText(m_restorePublicStore); 152 | m_localStore->setText(m_restoreLocalStore); 153 | QDialog::reject(); 154 | } 155 | -------------------------------------------------------------------------------- /src/MTuner/src/symbolstore.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_SYMBOLSTORE_H 7 | #define RTM_MTUNER_SYMBOLSTORE_H 8 | 9 | #include 10 | 11 | class SymbolStore : public QDialog 12 | { 13 | Q_OBJECT 14 | 15 | private: 16 | QCheckBox* m_srcRegistry; 17 | QLineEdit* m_localStore; 18 | QLineEdit* m_publicStore; 19 | QToolButton* m_buttonDefault; 20 | QToolButton* m_buttonBrowse; 21 | bool m_hasRegistryEntry; 22 | bool m_restoreRegistryChecked; 23 | QString m_restorePublicStore; 24 | QString m_restoreLocalStore; 25 | 26 | public: 27 | SymbolStore(QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 28 | 29 | void changeEvent(QEvent* _event); 30 | QString getSymbolStoreString() const; 31 | QString getLocalStore() const; 32 | void setLocalStore(const QString& _localStore); 33 | QString getPublicStore() const; 34 | void setPublicStore(const QString& _publicStore); 35 | bool isRegistryChecked() const; 36 | void setChecked(bool _registry); 37 | void save(); 38 | 39 | public Q_SLOTS: 40 | void selectLocalStore(); 41 | void defaultSymbolServer(); 42 | void visitMSDN(); 43 | 44 | virtual int exec(); 45 | virtual void accept(); 46 | virtual void reject(); 47 | 48 | private: 49 | Ui::SymbolStoreDialog ui; 50 | }; 51 | 52 | #endif // RTM_MTUNER_SYMBOLSTORE_H 53 | -------------------------------------------------------------------------------- /src/MTuner/src/tagtree.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | tagTree 4 | 5 | 6 | 7 | 0 8 | 0 9 | 1032 10 | 660 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | :/MTuner/resources/images/StackTree64.png:/MTuner/resources/images/StackTree64.png 19 | 20 | 21 | 22 | 0 23 | 24 | 25 | 0 26 | 27 | 28 | 0 29 | 30 | 31 | 0 32 | 33 | 34 | 35 | 36 | Qt::NoFocus 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /src/MTuner/src/tagtreewidget.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_TAGTREEWIDGET_H 7 | #define RTM_MTUNER_TAGTREEWIDGET_H 8 | 9 | #include 10 | 11 | class TagTreeItem; 12 | struct CaptureContext; 13 | 14 | class TagTreeModel : public QAbstractItemModel 15 | { 16 | Q_OBJECT 17 | 18 | private: 19 | CaptureContext* m_context; 20 | TagTreeItem* m_rootItem; 21 | 22 | public: 23 | TagTreeModel(CaptureContext* _context, QObject* _parent = 0); 24 | ~TagTreeModel(); 25 | 26 | QVariant data(const QModelIndex& _index, int _role) const; 27 | Qt::ItemFlags flags(const QModelIndex& _index) const; 28 | QVariant headerData(int _section, Qt::Orientation _orientation, int _role = Qt::DisplayRole) const; 29 | QModelIndex index(int _row, int _column, const QModelIndex& _parent = QModelIndex()) const; 30 | QModelIndex parent(const QModelIndex& _index) const; 31 | int rowCount(const QModelIndex& _parent = QModelIndex()) const; 32 | int columnCount(const QModelIndex& _parent = QModelIndex()) const; 33 | 34 | private: 35 | void setupModelData(const rtm::MemoryTagTree* _tree, TagTreeItem* _parent); 36 | }; 37 | 38 | class TagTreeWidget : public QWidget 39 | { 40 | Q_OBJECT 41 | 42 | CaptureContext* m_context; 43 | QTreeView* m_tree; 44 | 45 | public: 46 | TagTreeWidget(QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 47 | 48 | void changeEvent(QEvent* event); 49 | void setContext(CaptureContext* _context); 50 | void setupTree(); 51 | 52 | public Q_SLOTS: 53 | void rowClicked(const QModelIndex&); 54 | 55 | Q_SIGNALS: 56 | void setStackTrace(rtm::StackTrace**, int); 57 | void tagClicked(); 58 | 59 | private: 60 | Ui::tagTree ui; 61 | }; 62 | 63 | #endif // RTM_MTUNER_TAGTREEWIDGET_H 64 | -------------------------------------------------------------------------------- /src/MTuner/src/treemap.cpp: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #include 7 | #include 8 | 9 | TreeMapWidget::TreeMapWidget(QWidget* _parent, Qt::WindowFlags _flags) : 10 | QWidget(_parent, _flags) 11 | { 12 | ui.setupUi(this); 13 | m_graphicsView = findChild("graphicsView"); 14 | m_context = nullptr; 15 | m_map = nullptr; 16 | 17 | QComboBox* cb = findChild("comboBoxType"); 18 | connect(cb, SIGNAL(currentIndexChanged(int)), this, SLOT(treeMapTypeChanged(int))); 19 | 20 | m_scene = new QGraphicsScene(this); 21 | m_scene->setItemIndexMethod(QGraphicsScene::NoIndex); 22 | m_scene->setBackgroundBrush(QColor(33, 80, 90, 235)); 23 | 24 | m_graphicsView->setScene(m_scene); 25 | m_graphicsView->setViewportUpdateMode(QGraphicsView::FullViewportUpdate); 26 | connect(m_graphicsView, SIGNAL(setStackTrace(rtm::StackTrace**,int)), this, SIGNAL(setStackTrace(rtm::StackTrace**,int))); 27 | connect(m_graphicsView, SIGNAL(highlightTime(uint64_t)), this, SIGNAL(highlightTime(uint64_t))); 28 | connect(m_graphicsView, SIGNAL(highlightRange(uint64_t, uint64_t)), this, SIGNAL(highlightRange(uint64_t, uint64_t))); 29 | } 30 | 31 | void TreeMapWidget::changeEvent(QEvent* _event) 32 | { 33 | QWidget::changeEvent(_event); 34 | if (_event->type() == QEvent::LanguageChange) 35 | ui.retranslateUi(this); 36 | } 37 | 38 | void TreeMapWidget::setContext(CaptureContext* _context) 39 | { 40 | m_context = _context; 41 | m_graphicsView->setContext(_context); 42 | m_map = new TreeMapGraphicsItem(m_graphicsView, _context); 43 | m_scene->addItem(m_map); 44 | } 45 | 46 | void TreeMapWidget::setFilteringState(bool _state) 47 | { 48 | RTM_UNUSED(_state); 49 | m_graphicsView->setMapType(m_graphicsView->getMapType()); 50 | } 51 | 52 | void TreeMapWidget::treeMapTypeChanged(int _type) 53 | { 54 | m_graphicsView->setMapType(_type); 55 | } 56 | -------------------------------------------------------------------------------- /src/MTuner/src/treemap.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_TREEMAP_H 7 | #define RTM_MTUNER_TREEMAP_H 8 | 9 | #include 10 | #include 11 | 12 | class TreeMapWidget : public QWidget 13 | { 14 | Q_OBJECT 15 | 16 | private: 17 | QGraphicsScene* m_scene; 18 | CaptureContext* m_context; 19 | TreeMapView* m_graphicsView; 20 | TreeMapGraphicsItem* m_map; 21 | 22 | public: 23 | TreeMapWidget(QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 24 | 25 | void changeEvent(QEvent* _event); 26 | void setContext(CaptureContext* _context); 27 | void setFilteringState(bool _state); 28 | 29 | public Q_SLOTS: 30 | void treeMapTypeChanged(int _type); 31 | 32 | Q_SIGNALS: 33 | void setStackTrace(rtm::StackTrace**, int); 34 | void highlightTime(uint64_t); 35 | void highlightRange(uint64_t, uint64_t); 36 | 37 | private: 38 | Ui::TreeMap ui; 39 | }; 40 | 41 | #endif // RTM_MTUNER_TREEMAP_H 42 | -------------------------------------------------------------------------------- /src/MTuner/src/treemap.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | TreeMap 4 | 5 | 6 | 7 | 0 8 | 0 9 | 844 10 | 678 11 | 12 | 13 | 14 | true 15 | 16 | 17 | Form 18 | 19 | 20 | 21 | 0 22 | 23 | 24 | 0 25 | 26 | 27 | 0 28 | 29 | 30 | 0 31 | 32 | 33 | 0 34 | 35 | 36 | 37 | 38 | 0 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | Qt::Horizontal 49 | 50 | 51 | 52 | 208 53 | 20 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 150 63 | 0 64 | 65 | 66 | 67 | 68 | Memory usage 69 | 70 | 71 | 72 | 73 | Memory usage peak 74 | 75 | 76 | 77 | 78 | Allocation overhead 79 | 80 | 81 | 82 | 83 | Allocation overhead peak 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | Qt::Horizontal 92 | 93 | 94 | 95 | 208 96 | 20 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | TreeMapView 110 | QGraphicsView 111 |
../src/treemapview.h
112 |
113 |
114 | 115 | 116 |
117 | -------------------------------------------------------------------------------- /src/MTuner/src/treemapview.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_TREEMAPVIEW_H 7 | #define RTM_MTUNER_TREEMAPVIEW_H 8 | 9 | class TreeMapGraphicsItem; 10 | struct CaptureContext; 11 | 12 | struct TreeMapNode 13 | { 14 | rtm::StackTraceTree* m_tree; ///< Pointer to the actual stact trace tree node, used to resolve symbols 15 | uint64_t m_size; ///< Size of the node, based on the view type (usage, peak, etc.) 16 | QRectF m_rect; 17 | 18 | inline TreeMapNode() 19 | : m_tree(nullptr) 20 | , m_size(0) 21 | {} 22 | }; 23 | 24 | class TreeMapView : public QGraphicsView 25 | { 26 | Q_OBJECT 27 | 28 | private: 29 | CaptureContext* m_context; 30 | std::vector m_tree; 31 | QList m_treeLines; 32 | TreeMapNode* m_highlightNode; 33 | TreeMapNode* m_clickedNode; 34 | uint32_t m_mapType; 35 | TreeMapGraphicsItem* m_item; 36 | QLabel* m_toolTipLabel; 37 | 38 | public: 39 | TreeMapView(QWidget* _parent = 0); 40 | 41 | void setItem(TreeMapGraphicsItem* _item) { m_item = _item; } 42 | void setContext(CaptureContext* _context); 43 | void setMapType(uint32_t _type); 44 | uint32_t getMapType() const { return m_mapType; } 45 | void updateHighlight(const QPoint& _pos); 46 | inline TreeMapNode* getHighlightNode() { return m_highlightNode; } 47 | inline TreeMapNode* getClickedNode() { return m_clickedNode; } 48 | std::vector& getTree() { return m_tree; } 49 | QVector& getTreeLines() { return m_treeLines; } 50 | 51 | /// QWidget 52 | void resizeEvent(QResizeEvent* _event); 53 | void mousePressEvent(QMouseEvent* _event); 54 | void mouseMoveEvent(QMouseEvent* _event); 55 | void mouseReleaseEvent(QMouseEvent* _event); 56 | void enterEvent(QEnterEvent *event); 57 | void leaveEvent(QEvent *event); 58 | 59 | Q_SIGNALS: 60 | void setStackTrace(rtm::StackTrace**, int); 61 | void highlightTime(uint64_t); 62 | void highlightRange(uint64_t, uint64_t); 63 | 64 | private: 65 | void buildTreeRecurse(rtm::StackTraceTree* _tree); 66 | void buildTree(); 67 | }; 68 | 69 | class TreeMapGraphicsItem : public QGraphicsItem 70 | { 71 | private: 72 | QRectF m_oldRect; 73 | TreeMapView* m_treeView; 74 | CaptureContext* m_context; 75 | 76 | public: 77 | TreeMapGraphicsItem(TreeMapView* _treeView, CaptureContext* _context); 78 | 79 | void redraw(); 80 | void parentResized() { prepareGeometryChange(); } 81 | 82 | /// QWidget 83 | virtual QRectF boundingRect() const; 84 | virtual void paint(QPainter* _painter, const QStyleOptionGraphicsItem* _option, QWidget* _widget); 85 | }; 86 | 87 | #endif // RTM_MTUNER_TREEMAPVIEW_H 88 | -------------------------------------------------------------------------------- /src/MTuner/src/version.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_VERSION_H 7 | #define RTM_MTUNER_VERSION_H 8 | 9 | static const char* MTunerVersion = "4.9"; 10 | 11 | #endif // RTM_MTUNER_VERSION_H 12 | -------------------------------------------------------------------------------- /src/MTuner/src/welcome.cpp: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #include 7 | #include 8 | 9 | WelcomeDialog::WelcomeDialog(QWidget* _parent, Qt::WindowFlags) : 10 | QDialog(_parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint) 11 | { 12 | ui.setupUi(this); 13 | 14 | connect(ui.buttonSymbols, &QPushButton::clicked, this, &WelcomeDialog::setupSymbols); 15 | connect(ui.buttonDocumentation, &QPushButton::clicked, this, &WelcomeDialog::readDocumentation); 16 | } 17 | 18 | void WelcomeDialog::changeEvent(QEvent* _event) 19 | { 20 | QDialog::changeEvent(_event); 21 | if (_event->type() == QEvent::LanguageChange) 22 | ui.retranslateUi(this); 23 | } 24 | 25 | bool WelcomeDialog::shouldShowNextTime() const 26 | { 27 | return ui.checkBox->isChecked(); 28 | } 29 | -------------------------------------------------------------------------------- /src/MTuner/src/welcome.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------// 2 | /// Copyright 2025 Milos Tosic. All Rights Reserved. /// 3 | /// License: http://www.opensource.org/licenses/BSD-2-Clause /// 4 | //--------------------------------------------------------------------------// 5 | 6 | #ifndef RTM_MTUNER_WELCOME_H 7 | #define RTM_MTUNER_WELCOME_H 8 | 9 | #include 10 | 11 | class WelcomeDialog : public QDialog 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | WelcomeDialog(QWidget* _parent = 0, Qt::WindowFlags _flags = (Qt::WindowFlags)0); 17 | void changeEvent(QEvent* _event); 18 | 19 | bool shouldShowNextTime() const; 20 | 21 | Q_SIGNALS: 22 | void setupSymbols(); 23 | void readDocumentation(); 24 | 25 | private: 26 | Ui::Welcome ui; 27 | }; 28 | 29 | #endif // RTM_MTUNER_WELCOME_H 30 | --------------------------------------------------------------------------------