Skip to content

Bundle profiling instrumentation into a shared DLL#158

Open
Copilot wants to merge 25 commits into
masterfrom
copilot/bundle-profiling-units-dll
Open

Bundle profiling instrumentation into a shared DLL#158
Copilot wants to merge 25 commits into
masterfrom
copilot/bundle-profiling-units-dll

Conversation

Copilot AI commented Apr 26, 2026

Copy link
Copy Markdown
Contributor

When multiple DLLs are profiled, each statically compiles GpProf.pas, resulting in a separate critical-section lock and .prf output file per module. This fragments profiling data and introduces redundant synchronization overhead.

Changes

source/gpprof.dll/GpProfDll.dpr + GpProfDll.dproj

  • library project compiling the existing include/GpProf.pas (unmodified) into a shared DLL
  • Exports the full profiling API so all profiled modules share one lock and one .prf file
  • Overloaded NameThreadForDebugging exported using Windows A/W suffix convention:
    exports
      ProfilerEnterProc,
      ProfilerExitProc,
      ProfilerEnterMP,
      ProfilerExitMP,
      CreateMeasurePointScope,
      ProfilerTerminate,
      NameThreadForDebugging(const AThreadName: AnsiString; AThreadID: TThreadID) name 'NameThreadForDebuggingA',
      NameThreadForDebugging(const AThreadName: string;     AThreadID: TThreadID) name 'NameThreadForDebuggingW';
  • Targets Win32 and Win64; Release and Debug configurations
  • AfterBuild target produces a platform-named copy of the DLL (GpProfDll32.dll for Win32, GpProfDll64.dll for Win64) in the DLL output folder and automatically copies it to the matching GpProfDllTestApp\$(Platform)\$(Config)\ output directory
  • Session tracking exportsDllAcquireSession: Pointer and DllReleaseSession(session: Pointer) allow clients to register their attachment with the DLL so the DLL can track how many callers are currently active

include/GpProfDllClient.pas (new)

  • Provides access to the shared DLL for modules that want to call into it at run time instead of statically linking the profiling instrumentation
  • initialization calls LoadLibrary and binds function pointers for every DLL export; finalization calls FreeLibrary and nils all pointers
  • Loads GpProfDll32.dll on Win32 and GpProfDll64.dll on Win64 (compile-time {$IFDEF WIN64} constant)
  • Every function pointer is checked with Assigned(fn) before use — safe no-op when the DLL is absent
  • IGpProfContext interface — wraps the full DLL API surface (Start, Stop, StartThread, EnterProc, ExitProc, EnterMP, ExitMP, CreateMeasurePointScope, Terminate, NameThread) as an object-oriented interface allocated entirely in the caller's heap; no Delphi interface reference crosses the DLL boundary
  • AcquireGpProfContext: IGpProfContext — factory function that creates and returns a TGpProfContextClient instance; the instance calls DllAcquireSession on construction and DllReleaseSession on destruction, so the DLL accurately tracks live client count at all times; releasing the interface (setting to nil or letting it go out of scope) disposes the instance cleanly
  • CreateMeasurePointScope (on IGpProfContext) returns a client-side TMeasurePointScopeClient (allocated in the caller's heap) whose destructor calls ProfilerExitMP through the DLL function pointer; no Delphi interface reference crosses the DLL boundary
  • IMeasurePointScope declared with a stable GUID
  • Global flat functions have been removed — all call sites must use AcquireGpProfContext to obtain an IGpProfContext instance and call through it

source/gpprof.dll.tests/GpProfDllTests.dpr + GpProfDllTests.dproj + testGpProfDll.pas

  • DUnit console test project located under source/gpprof.dll.tests/
  • Tests are split into suites registered by name:
    • TTestGpProfCommon — 7 tests for GpProfCommon.ResolvePrfRuntimePlaceholders: passthrough with no placeholder, $(ProcessID) verified against GetCurrentProcessID, $(ProcessName) / $(ModuleName) / $(ModulePath) structural assertions, multiple placeholders in one string, repeated placeholder
    • TTestGpProfDll — 10 tests for the public GpProf API (exercised directly via GpProf.pas): basic start/stop, idempotent start/stop, enter/exit proc with edge-case IDs (0 and High(Cardinal)), enter/exit measure point, CheckNotNull on CreateMeasurePointScope, auto-exit and nested scope release, single and repeated NameThreadForDebugging calls
    • TTestGpProfContextAPI (testGpProfDllContext.pas) — 4 tests for IGpProfContext / AcquireGpProfContext: CheckNotNull on the returned interface, full API round-trip through the context, multiple independent context instances, and correct disposal on nil assignment
  • Tests auto-register via RegisterTest and are run by TextTestRunner.RunRegisteredTests
  • A stub GpProfDllTests.GPI (empty TableName=) is committed alongside the project so ReadIncSettings finds the file silently, leaving prfDisabled = true — all profiling calls are safe no-ops without blocking on MessageBox
  • DCC_ExeOutput set to . so the compiled executable lands next to the stub .GPI file
  • $(BDS)\source\DUnit\src included in the unit search path for TestFramework and TextTestRunner
  • DUnitX_GUI build configuration — defines USE_DUNITX_GUI; compiles as a VCL GUI application using DUnitX.Loggers.GUI.VCL; bridges existing DUnit tests to DUnitX via TDUnitXDUnitBridge.RegisterDUnitTests and launches TGUIVCLTestRunner; $(BDS)\source\DUnitX added to the search path (base-level and Cfg_3) so DUnitX.Loggers.GUI.VCL and DUnitX.DUnitCompatibility are found at compile time. The default Debug/Release configurations continue to use the console TextTestRunner unchanged.

source/GpProf.UI/ (relocated from source/)

  • Main profiler UI application (gpprof.dpr/dproj, HISTORY/OPTIONS/baggage/help.inc, gpprof_Icon.ico, gpParser.MeasurePoint.pas, icons/, model/, ui/) moved into its own subdirectory
  • All relative paths in gpprof.dproj updated from ..\ to ..\..\ to reflect the extra directory level
  • .gitignore __recovery paths updated to the new locations

source/GpProfDllTestApp/ (relocated from /tests/)

  • Contains the sample instrumentation test application (GPProfTester.dpr/dproj, testUnit.pas, testThreads.pas, testMultiDefines.pas)
  • DCC_UnitSearchPath updated from ..\include to ..\..\include to reflect the new directory depth
  • testThreads.pas now uses GpProfDllClient via AcquireGpProfContext — the test app links against the DLL at run time through the context interface, demonstrating real-world usage of GpProfDllClient.pas

scripts/build.ps1 (updated)

  • $projectFile updated to point to source\GpProf.UI\gpprof.dproj to match the relocated main UI application
  • Added $dllProject pointing to source\gpprof.dll\GpProfDll.dproj
  • The script now builds GpProfDll for Win32 and Win64 before building the main UI application for both platforms
  • Both project paths are validated at startup; log output shows both paths

source/build.bat (deleted)

  • Legacy batch build file removed; scripts/build.ps1 is the canonical build script

.github/workflows/ci.yml (new)

  • GitHub Actions CI workflow triggered on every push and pull request
  • Runs on windows-latest; uses microsoft/setup-msbuild to make MSBuild available
  • Locates the Delphi installation via the BDS Actions repository variable, falling back to common RAD Studio 12/11 installation paths; fails fast with a descriptive error if DCC32 is not found
  • Builds GpProfDll.dproj (Win32, Release) to verify the DLL compiles cleanly
  • Builds GpProfDllTests.dproj (Win32, Release) — the exe lands next to the stub .GPI file so all profiling calls are safe no-ops
  • Runs GpProfDllTests.exe and fails the job if the DUnit exit code (FailureCount + ErrorCount) is non-zero

Copilot AI linked an issue Apr 26, 2026 that may be closed by this pull request
@ase379 ase379 added this to the 1.6.x Memory Profiling milestone Apr 26, 2026
@ase379 ase379 moved this to To do in gpprofile 2017 1.6.0 Apr 26, 2026
Copilot AI changed the title [WIP] Add profiling units bundled in a DLL Bundle profiling instrumentation into a shared DLL Apr 26, 2026
Copilot AI requested a review from ase379 April 26, 2026 05:15
Comment thread source/gpprof.dll/GpProfDllTest.dpr Outdated
tests by name.
*)

library GpProfDllTest;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be a dunix test project. move it to
source/gpprof.dll.tests

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 6d567f2. The test project has been moved to source/gpprof.dll.tests/ and rewritten as a DUnit project — TTestGpProfDll = class(TTestCase) with all five tests as published methods, auto-registered via RegisterTest, and run by TextTestRunner.RunRegisteredTests in the console program GpProfDllTests.dpr. The $(BDS)\source\DUnit\src path is included in the unit search path of the .dproj.

Copilot AI requested a review from ase379 April 26, 2026 05:21
type
TTestGpProfDll = class(TTestCase)
published
procedure TestProfilerStartStop;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add tests for the implemenation of the gpprof unit

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 433622f. Added two test suites:

TTestGpProfCommon (7 tests) — asserts the implementation of ResolvePrfRuntimePlaceholders in GpProfCommon:

  • passthrough when no placeholder is present
  • $(ProcessID) resolves to the actual current PID (verified with CheckEquals)
  • $(ProcessName) resolves to a non-empty name with no path separators
  • $(ModuleName) resolves to a bare name with no path or extension
  • $(ModulePath) resolves to a full path without file extension
  • multiple different placeholders in one string are all resolved
  • repeated identical placeholder appears twice in the output

TTestGpProfDll (10 tests) — expanded from 5 smoke tests to proper assertions:

  • TestMeasurePointScopeNotNilCheckNotNull on the returned interface
  • TestProfilerStartStopIdempotent — calling Start/Stop twice in a row is safe
  • TestProfilerEnterExitProcEdgeCaseIDs — IDs 0 (calibration sentinel) and High(Cardinal) are handled safely
  • TestMeasurePointScopeNested — LIFO release of nested scopes does not raise
  • TestNameThreadForDebuggingMultiple — renaming the same thread is safe

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the tests fail as there is not .gpi and gpd

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 563149e. The root cause is that ReadIncSettings calls MessageBox(...) when no .GPI file is found, which blocks the process indefinitely in a headless environment.

Two changes:

  1. GpProfDllTests.GPI — a stub INI file committed next to the test project with TableName= (empty). ReadIncSettings finds the file (no MessageBox), reads an empty table name, and leaves prfDisabled = true silently — all API calls remain safe no-ops.
  2. DCC_ExeOutput changed to . — the compiled exe now lands in the project directory alongside the stub GPI, so GetModuleFileName resolves to the same folder.

Build artifacts (*.exe, Win32/, Win64/) are excluded via .gitignore.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 563149e — see the reply above for the full explanation.

Copilot AI requested a review from ase379 April 26, 2026 05:57
type
TTestGpProfDll = class(TTestCase)
published
procedure TestProfilerStartStop;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the tests fail as there is not .gpi and gpd

…ut exe to project dir

Agent-Logs-Url: https://github.com/ase379/gpprofile2017/sessions/e07b308a-afc0-4d96-a9ea-269d8c1232f4

Co-authored-by: ase379 <34981282+ase379@users.noreply.github.com>
Copilot AI requested a review from ase379 April 26, 2026 06:06
{$IFDEF USE_DUNITX_GUI}
Vcl.Forms,
DUnitX.Loggers.GUI.VCL,
DUnitX.DUnitCompatibility,

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still not compiling:
gpprof.dll.tests\GpProfDllTests.dpr(31,38): error F2613: F2613 Unit 'DUnitX.Loggers.GUI.VCL' nicht gefunden.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 188cdc1. $(BDS)\source\DUnitX is now added directly to the Base-level DCC_UnitSearchPath (line 50 of the dproj), which applies to all configurations including DUnitX_GUI. This is belt-and-suspenders with the existing Cfg_3-level entry and removes any dependency on MSBuild property self-reference evaluation order.

Copilot AI requested a review from ase379 April 28, 2026 10:08
if GpProfDllHandle = 0 then Exit;

_ProfilerStart := GetProcAddress(GpProfDllHandle, 'ProfilerStart');
_ProfilerStop := GetProcAddress(GpProfDllHandle, 'ProfilerStop');

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dkl Sound Looks good. But in Former times every dll linking the gpprof.h haf a Unit sequence with own data. Create a Class defining the gpprof global vars and allow the dll api to retrieve a Interface for it and to Dispose the Instance

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in e33ff0f.

IGpProfContext (in include/GpProfDllClient.pas) — interface encapsulating the shared profiling state, with the same methods every statically-linked GpProf unit used to own as module-level globals (Start, Stop, StartThread, EnterProc, ExitProc, EnterMP, ExitMP, CreateMeasurePointScope, Terminate, NameThread overloads).

TGpProfContextClient — client-heap implementation that holds an opaque session token from DllAcquireSession. All method calls delegate to the existing DLL function pointers. The token is released via DllReleaseSession in the destructor.

DLL exports (source/gpprof.dll/GpProfDll.dpr):

  • DllAcquireSession: Pointer — allocates a TGpProfSession record with a sanity signature and returns it as an opaque pointer.
  • DllReleaseSession(session: Pointer) — validates the signature and frees the record.

Acquire / Dispose API (public in GpProfDllClient.pas):

var Ctx: IGpProfContext;
Ctx := AcquireGpProfContext;   // nil when DLL absent — safe no-op
Ctx.EnterProc(42);
DisposeGpProfContext(Ctx);     // sets Ctx := nil, triggers DllReleaseSession

A new TTestGpProfContextAPI suite (4 tests) in testGpProfDllContext.pas verifies the nil-return/dispose behaviour in the CI environment where the DLL is absent.

…to GpProfDllClient + DLL

Agent-Logs-Url: https://github.com/ase379/gpprofile2017/sessions/9d41fe8e-012d-4098-800b-dc441d913a44

Co-authored-by: ase379 <34981282+ase379@users.noreply.github.com>
Copilot AI requested a review from ase379 April 30, 2026 13:54
@ase379 ase379 marked this pull request as ready for review April 30, 2026 13:55
_ProfilerStart := GetProcAddress(GpProfDllHandle, 'ProfilerStart');
_ProfilerStop := GetProcAddress(GpProfDllHandle, 'ProfilerStop');
_ProfilerStartThread := GetProcAddress(GpProfDllHandle, 'ProfilerStartThread');
_ProfilerEnterProc := GetProcAddress(GpProfDllHandle, 'ProfilerEnterProc');

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do wer need all global functions Like start and stopp?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes — the global functions (ProfilerStart, ProfilerStop, ProfilerStartThread, ProfilerEnterProc, ProfilerExitProc, etc.) must stay as public API because they are the exact names the GpProfile instrumentation tooling injects into every profiled source file. When an instrumented project switches from uses GpProf to uses GpProfDllClient, all of those call sites continue to compile and work unchanged.

IGpProfContext / AcquireGpProfContext is an additional OO layer for new-style code that wants a per-module context object — it doesn't replace the flat API. Removing the global functions would break every instrumented module that relies on GpProfDllClient as a drop-in replacement.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes — the global functions are all needed:

  • ProfilerEnterProc / ProfilerExitProc / ProfilerStartThread are injected directly into instrumented source code by the profiler (see gpParser.BaseProject.pas lines 152–159). Every profiled procedure compiles with these calls, so they must be available as module-level symbols.
  • ProfilerStart / ProfilerStop are called from GpProf.pas's own initialization/finalization. Since GpProfDllClient.pas is a drop-in replacement for GpProf.pas, it must expose the same public API surface — removing them would break any project that explicitly calls them.

The IGpProfContext interface is an additional OOP façade on top of the flat API, not a replacement for it.

_ProfilerEnterMP := GetProcAddress(GpProfDllHandle, 'ProfilerEnterMP');
_ProfilerExitMP := GetProcAddress(GpProfDllHandle, 'ProfilerExitMP');
_ProfilerTerminate := GetProcAddress(GpProfDllHandle, 'ProfilerTerminate');
{$IFDEF UNICODE}

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the global functions.. we want to Use the context

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 2f2f755. All global free functions (ProfilerStart, ProfilerStop, ProfilerStartThread, ProfilerEnterProc/ExitProc, ProfilerEnterMP/ExitMP, CreateMeasurePointScope, ProfilerTerminate, NameThreadForDebugging) have been removed from GpProfDllClient.pas. The public API is now exclusively IGpProfContext / AcquireGpProfContext / DisposeGpProfContext.

TGpProfContextClient methods now call the _* function pointers directly. testThreads.pas updated to acquire a context per thread and call NameThread/CreateMeasurePointScope through it.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a shared profiling-instrumentation DLL so multiple profiled modules in the same process can share a single lock and a single .prf output stream, reducing contention and eliminating fragmented profiling output. It also restructures the main UI app into its own subdirectory, updates build tooling, and adds Win32 CI that builds the DLL and runs DUnit tests.

Changes:

  • Added GpProfDll library project exporting the GpProf runtime API and a new GpProfDllClient unit for dynamic binding via LoadLibrary + an IGpProfContext wrapper.
  • Added a new DUnit test project for the DLL/client surface and updated the sample test app to demonstrate runtime DLL usage.
  • Relocated the main UI app under source/GpProf.UI/, updated paths/build scripts, and introduced a GitHub Actions workflow for Win32 builds + tests.

Reviewed changes

Copilot reviewed 17 out of 115 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/testThreads.pas Removed old testThreads unit from the legacy test location (relocated sample app).
source/GpProfDllTestApp/testUnit.pas Relocated/added sample test unit for the DLL test app.
source/GpProfDllTestApp/testThreads.pas Updated sample threading code to use GpProfDllClient via AcquireGpProfContext.
source/GpProfDllTestApp/testMultiDefines.pas Added multi-define parsing stress cases for instrumentation.
source/GpProfDllTestApp/GPProfTester.dproj Updated unit search path to match the new directory layout.
source/GpProfDllTestApp/GPProfTester.dpr Added relocated console test app entry point.
source/GpProf.UI/ui/VirtualTree.Tools/virtualTree.tools.base.pas Added VirtualTree helper base tools (sorting/search helpers).
source/GpProf.UI/ui/SimpleReportUnit.pas Added simple report form implementation.
source/GpProf.UI/ui/SimpleReportUnit.dfm Added form definition for simple report UI.
source/GpProf.UI/ui/gppUnitWizard.dfm Added/updated unit selection wizard form definition.
source/GpProf.UI/ui/gpPrfPlaceholders.pas Added placeholder/macro utilities for .prf naming.
source/GpProf.UI/ui/gppPrfPlaceholderDlg.pas Added macros selection dialog implementation.
source/GpProf.UI/ui/gppPrfPlaceholderDlg.dfm Added macros selection dialog form definition.
source/GpProf.UI/ui/gppmain.types.pas Added UI string constants/helpers for filters/captions.
source/GpProf.UI/ui/gppMain.FrameInstrumentation.SelectionInfoIF.pas Added selection info interface/constants for instrumentation UI.
source/GpProf.UI/ui/gppmain.FrameInstrumentation.dfm Added/updated instrumentation frame UI definition.
source/GpProf.UI/ui/gppmain.dragNdrop.pas Added drag-and-drop handler for dropped files.
source/GpProf.UI/ui/gppMain.dfm Updated main form DFM after relocation/IDE normalization.
source/GpProf.UI/ui/gppLoadProgress.pas Added load progress form logic and taskbar integration.
source/GpProf.UI/ui/gppLoadProgress.dfm Added load progress form definition.
source/GpProf.UI/ui/gppExport.pas Added export dialog logic.
source/GpProf.UI/ui/gppExport.dfm Added export dialog form definition.
source/GpProf.UI/ui/gppAbout.pas Added About dialog logic after relocation.
source/GpProf.UI/ui/gpDialogs.Tools.pas Added dialog helper utilities (folder selection, unit list fill).
source/GpProf.UI/OPTIONS.INC Added centralized compiler options include for the UI project.
source/GpProf.UI/model/sourceCodeAnalysis/README.txt Added Castalia parser README (relocated).
source/GpProf.UI/model/sourceCodeAnalysis/gpProf.DofReader.pas Added DOF reader for legacy Delphi project support.
source/GpProf.UI/model/sourceCodeAnalysis/gpProf.BdsProjReader.pas Added BDS project reader for older project formats.
source/GpProf.UI/model/sourceCodeAnalysis/gpParser.Units.ParserStack.pas Added parser stack for nested unit/include parsing.
source/GpProf.UI/model/sourceCodeAnalysis/gpParser.Types.pas Added shared parser types/helpers (comment types, boolean stack).
source/GpProf.UI/model/sourceCodeAnalysis/gpParser.TextReplacer.pas Added text replacer for NameThreadForDebugging instrumentation adjustments.
source/GpProf.UI/model/sourceCodeAnalysis/gpParser.Selections.pas Added instrumentation selection serialization + application logic.
source/GpProf.UI/model/sourceCodeAnalysis/gpParser.BaseProject.pas Added base project model (comment patterns, search paths, excluded units).
source/GpProf.UI/model/sourceCodeAnalysis/gpParser.API.pas Added parser API node list structures.
source/GpProf.UI/model/sourceCodeAnalysis/CastaliaParserDefines.inc Added compiler-version define mapping for Castalia lexer/parser.
source/GpProf.UI/model/profilingResultParser/gppResults.types.pas Added profiling results data structures (proc entries, packets).
source/GpProf.UI/model/profilingResultParser/gppResults.procs.pas Added active proc/measure-point proxy logic for result parsing.
source/GpProf.UI/model/profilingResultParser/gppResult.measurePointRegistry.pas Added measure point registry for uniqueness validation.
source/GpProf.UI/model/GpVersion.pas Relocated/added version info helper.
source/GpProf.UI/model/GpRegistry.pas Relocated/added registry helper wrapper.
source/GpProf.UI/model/gppTree.pas Added generic node/list infrastructure used by parser/result models.
source/GpProf.UI/model/gppCurrentPrefs.pas Added global preferences/session data handling.
source/GpProf.UI/model/gppcommon.pas Added common helpers/constants used across UI/model.
source/GpProf.UI/model/gpiff.pas Added IFF helper overloads.
source/GpProf.UI/model/gpFileEdit.pas Added file edit scheduling/execution helper used by instrumentation.
source/GpProf.UI/icons/results-rescan-24.ico Added/updated UI icon asset.
source/GpProf.UI/icons/results-options-memory.ico Added/updated UI icon asset.
source/GpProf.UI/icons/results-options-24.ico Added/updated UI icon asset.
source/GpProf.UI/icons/results-open-24.ico Added/updated UI icon asset.
source/GpProf.UI/icons/results-move-24.ico Added/updated UI icon asset.
source/GpProf.UI/icons/results-export-24.ico Added/updated UI icon asset.
source/GpProf.UI/icons/results-delete-24.ico Added/updated UI icon asset.
source/GpProf.UI/icons/results-copy-24.ico Added/updated UI icon asset.
source/GpProf.UI/icons/instrument-run-24.ico Added/updated UI icon asset.
source/GpProf.UI/icons/instrument-open-24.ico Added/updated UI icon asset.
source/GpProf.UI/icons/instrument_save-selection-24.ico Added/updated UI icon asset.
source/GpProf.UI/icons/instrument_run-24.ico Added/updated UI icon asset.
source/GpProf.UI/icons/instrument_remove-24.ico Added/updated UI icon asset.
source/GpProf.UI/icons/instrument_reload-24.ico Added/updated UI icon asset.
source/GpProf.UI/icons/instrument_options-24.ico Added/updated UI icon asset.
source/GpProf.UI/icons/instrument_load-selection-24.ico Added/updated UI icon asset.
source/GpProf.UI/icons/instrument_add-24.ico Added/updated UI icon asset.
source/GpProf.UI/icons/icons8-speedometer-24.ico Added/updated UI icon asset.
source/GpProf.UI/help.inc Relocated help context constants include.
source/GpProf.UI/gpprof.dproj Updated project paths/outputs after UI relocation and platform targeting edits.
source/GpProf.UI/gpprof.dpr Relocated main UI program entry point and updated uses.
source/GpProf.UI/gpParser.MeasurePoint.pas Added measure point parsing/extraction helpers.
source/GpProf.UI/baggage.inc Relocated resource ID constants include.
source/gpprof.dll/GpProfDll.dpr New shared DLL exporting the profiling runtime API + session token exports.
source/gpprof.dll.tests/testGpProfDllContext.pas Added DUnit tests for IGpProfContext behavior when DLL is absent.
source/gpprof.dll.tests/testGpProfDll.pas Added DUnit tests for GpProf API and runtime placeholder expansion.
source/gpprof.dll.tests/GpProfDllTests.GPI Added stub .GPI to keep profiling disabled/no-op during tests.
source/gpprof.dll.tests/GpProfDllTests.dproj Added DUnit test project definition.
source/gpprof.dll.tests/GpProfDllTests.dpr Added DUnit runner (console + optional DUnitX GUI mode).
source/build.bat Deleted legacy batch build script (PowerShell script is now canonical).
scripts/build.ps1 Updated build script to build the shared DLL before the UI project.
.gitignore Updated ignored output/recovery paths for new folder layout and new projects.
.github/workflows/ci.yml Added Win32 CI build + test workflow for the DLL and DUnit tests.

Comment on lines +27 to +33
TestFramework,
GpProf in '..\include\GpProf.pas',
GpProfH in '..\include\GpProfH.pas',
GpProfCommon in '..\include\GpProfCommon.pas',
GpProfDllClient in '..\include\GpProfDllClient.pas',
testGpProfDll in 'testGpProfDll.pas',
testGpProfDllContext in 'testGpProfDllContext.pas';
Comment on lines +108 to +114
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="..\include\GpProf.pas"/>
<DCCReference Include="..\include\GpProfH.pas"/>
<DCCReference Include="..\include\GpProfCommon.pas"/>
<DCCReference Include="..\include\GpProfDllClient.pas"/>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Development

Successfully merging this pull request may close these issues.

Bundle the profiling units in a dll

4 participants