<feed xmlns='http://www.w3.org/2005/Atom'>
<title>slang.git/source/core/slang-process-util.h, branch master</title>
<subtitle>Making it easier to work with shaders</subtitle>
<id>https://git.yummers.dev/slang.git/atom?h=master</id>
<link rel='self' href='https://git.yummers.dev/slang.git/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/'/>
<updated>2025-07-31T21:32:02+00:00</updated>
<entry>
<title>Handle debug-layer messages in a separate channel (#7988)</title>
<updated>2025-07-31T21:32:02+00:00</updated>
<author>
<name>Jay Kwak</name>
<email>82421531+jkwak-work@users.noreply.github.com</email>
</author>
<published>2025-07-31T21:32:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=aefd1e3e0dbe4e77f8d7dbbfa04e15c2db615394'/>
<id>urn:sha1:aefd1e3e0dbe4e77f8d7dbbfa04e15c2db615394</id>
<content type='text'>
* Handle debug-layer messages in a separate channel

The Problem (Issue #7343)

The issue was that Vulkan Validation Layer error messages were being mixed into regular test output, causing
potential false positives or negatives. When using -enable-debug-layers true, validation messages would appear in
the same output stream as test results, potentially matching //CHECK: patterns incorrectly.

Example Problem:
- Test expects: //CHECK: 1
- Validation layer prints: VALIDATION ERROR: 1 invalid buffer binding
- Test incorrectly matches the "1" in the error message instead of the actual output

Slang Test Communication Architecture

Execution Modes

Slang has 3 different execution modes controlled by SpawnType:

enum class SpawnType {
    UseSharedLibrary,              // In-process execution
    UseTestServer,                 // Out-of-process via persistent server
    UseFullyIsolatedTestServer,    // Out-of-process via isolated server
    UseExe                         // Direct executable spawn
}

1. In-Process Mode (UseSharedLibrary)

┌─────────────────────────────────────────┐
│              slang-test                 │
│  ┌─────────────┐    ┌─────────────────┐ │
│  │render-test  │    │gfx-unit-test    │ │
│  │unit-test    │    │slangc library   │ │
│  └─────────────┘    └─────────────────┘ │
│           │                   │         │
│           └───► StdWriters ◄──┘         │
│                 (shared)                │
└─────────────────────────────────────────┘
- Communication: Direct function calls, shared memory
- Debug callbacks: Single callback instance in StdWriters
- Used when: Default mode for most tests

2. Out-of-Process Mode (UseTestServer)

┌──────────────────┐    JSON-RPC     ┌──────────────────┐
│   slang-test     │◄──over pipes────┤ test-server.exe  │
│                  │                 │                  │
│  ┌─────────────┐ │                 │ ┌─────────────┐  │
│  │StdWriters   │ │                 │ │render-test  │  │
│  │+debug       │ │                 │ │gfx-unit-test│  │
│  │callback     │ │                 │ │+debug       │  │
│  └─────────────┘ │                 │ │callback     │  │
└──────────────────┘                 │ └─────────────┘  │
                                     └──────────────────┘
- Communication: JSON-RPC over stdin/stdout pipes
- Debug callbacks: Separate instances in each process
- Used when: CI/CD, multi-threaded testing, crash isolation

3. Direct Executable Mode (UseExe)

┌──────────────────┐    pipes       ┌──────────────────┐
│   slang-test     │◄───────────────┤  slangc.exe      │
│                  │                │  other tools     │
└──────────────────┘                └──────────────────┘
- Communication: Standard process pipes (stdout/stderr)
- Debug callbacks: None (external executables)
- Used when: Testing external tools

Communication Mechanisms Deep Dive

JSON-RPC Protocol Over Pipes

The test-server.exe communicates with slang-test using JSON-RPC over stdin/stdout pipes:

// Parent process (slang-test) creates child with pipes
Process* testServerProcess = /* spawn test-server.exe */;

// JSONRPCConnection wraps the pipe communication
JSONRPCConnection connection;
connection.initWithStdStreams(); // Uses stdin/stdout pipes

// Send RPC call
TestServerProtocol::ExecutionResult result;
connection.sendCall("executeTool", &amp;args, &amp;result);

Key Point: The pipes carry structured JSON messages, not raw stdout/stderr. This is what enables clean separation
of different data channels.

Protocol Structure

Your changes extend the ExecutionResult protocol:

struct ExecutionResult {
    String stdOut;      // Regular program output
    String stdError;    // Error messages
    String debugLayer;  // NEW: Debug/validation messages
    int32_t result;
    int32_t returnCode;
};

Your Debug Layer Solution

The Challenge

Memory pointers cannot cross process boundaries. A debugCallback pointer in the parent process is meaningless in
the child process.

The Solution: String-Based Serialization

You solved this by using string capture and serialization:

1. Debug Callback Interface (slang-std-writers.h)

class IDebugCallback {
    virtual void handleMessage(
        DebugMessageType type,
        DebugMessageSource source,
        const char* message) = 0;
};

2. String-Capturing Implementation (slang-support.h)

class CoreDebugCallback : public Slang::IDebugCallback {
    StringBuilder m_buf;  // Captures messages as strings

    void handleMessage(DebugMessageType type, DebugMessageSource source, const char* message) {
        if (type == DebugMessageType::Error) {
            m_buf &lt;&lt; message &lt;&lt; '\n';  // Serialize to string
        }
    }

    String getString() { return m_buf.toString(); }  // Extract accumulated messages
};

3. Bridge Between RHI and Core (slang-support.h)

class CoreToRHIDebugBridge : public rhi::IDebugCallback {
    Slang::IDebugCallback* m_coreCallback;

    void handleMessage(rhi::DebugMessageType type, rhi::DebugMessageSource source, const char* message) {
        // Convert RHI types to core types and forward
        m_coreCallback-&gt;handleMessage(convertType(type), convertSource(source), message);
    }
};

Data Flow: Debug Messages End-to-End

In-Process Mode Flow

GPU Driver → RHI Debug Callback → Core Debug Callback → String Buffer → Test Output

Out-of-Process Mode Flow

Child Process:
GPU Driver → RHI Debug Callback → Core Debug Callback → String Buffer
                                                              ↓
Parent Process:                                    JSON-RPC Serialization
Test Output ← String Processing ← ExecutionResult.debugLayer ←┘

Step-by-Step Example

1. Test Execution Starts
// In test-server process
CoreDebugCallback debugCallback;
CoreToRHIDebugBridge bridge;
bridge.setCoreCallback(&amp;debugCallback);

// Set up graphics device with debug layers
deviceDesc.debugCallback = &amp;bridge;
2. Graphics API Call Triggers Validation Error
// Inside Vulkan driver (external code)
// Validation layer detects error and calls our callback
bridge.handleMessage(RHI_ERROR, RHI_LAYER, "Invalid buffer binding");
3. Message Capture
// In CoreDebugCallback::handleMessage
m_buf &lt;&lt; "Invalid buffer binding\n";  // Stored in string buffer
4. Test Completion &amp; Serialization
// Back in test-server
TestServerProtocol::ExecutionResult result;
result.debugLayer = debugCallback.getString();  // "Invalid buffer binding\n"
result.stdOut = "1";  // Regular test output

// Send via JSON-RPC
connection.sendResult(&amp;result);
5. Parent Process Receives &amp; Separates Output
// In slang-test process
String output = buildTestOutput(result);
// Results in clean separation:
// standard output = {
// 1
// }
// debug layer = {
// Invalid buffer binding
// }

Why This Solution Works

1. Process Isolation: Each process has its own callback objects, no shared pointers
2. String Serialization: Debug messages converted to strings that can cross process boundaries
3. Protocol Extension: Uses existing JSON-RPC infrastructure, just adds new field
4. Clean Separation: Debug messages never mix with stdout/stderr
5. Backward Compatibility: Existing tests unaffected, debug layer field optional

Key Benefits

- Eliminates False Positives: Debug messages can't interfere with //CHECK: patterns
- Better Debugging: Debug messages clearly separated and labeled
- Robust Architecture: Works across all execution modes
- Minimal Changes: Leverages existing communication infrastructure

This elegant solution transforms a fundamental cross-process communication challenge into a simple string
serialization problem, using the existing test server architecture to cleanly separate validation layer messages
from test results.

* Cover the missing slang-test execution path

* format code (#82)

Co-authored-by: slangbot &lt;186143334+slangbot@users.noreply.github.com&gt;

---------

Co-authored-by: slangbot &lt;ellieh+slangbot@nvidia.com&gt;
Co-authored-by: slangbot &lt;186143334+slangbot@users.noreply.github.com&gt;</content>
</entry>
<entry>
<title>format</title>
<updated>2024-10-29T06:49:26+00:00</updated>
<author>
<name>Ellie Hermaszewska</name>
<email>ellieh@nvidia.com</email>
</author>
<published>2024-10-29T06:49:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=f65d756bff8d4c5cbc15bd0322a2ae8e6b896a21'/>
<id>urn:sha1:f65d756bff8d4c5cbc15bd0322a2ae8e6b896a21</id>
<content type='text'>
* format

* Minor test fixes

* enable checking cpp format in ci</content>
</entry>
<entry>
<title>Interprocess communication via pipes (#2009)</title>
<updated>2021-11-10T22:33:22+00:00</updated>
<author>
<name>jsmall-nvidia</name>
<email>jsmall@nvidia.com</email>
</author>
<published>2021-11-10T22:33:22+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=8a9e518371df03b3f382e0fe869da83751fdda0b'/>
<id>urn:sha1:8a9e518371df03b3f382e0fe869da83751fdda0b</id>
<content type='text'>
* #include an absolute path didn't work - because paths were taken to always be relative.

* Use 'Process' to communicate with an command line tool.

* Remove slang-win-stream

* Tidy up windows ProcessUtil.

* First version of BufferedReadStream.

* Windows working IPC for steams.

* Test proxy count option.

* Split Process/ProcessUtil. Process is platform dependant. ProcessUtil are functions that are platform independent.

* First implementation of Unix Process interface.

* Unix process compiles on cygwin.

* Fix typo in unix process.

* Separate unix pipe stream error of invalid access, from pipe availability.

* Fix in standard line extraction.

* Make fd non blocking.

* Fix issues with Windows Process streams.

* Added UnixPipe.

* Some fixes around UnixPipeStream.

* Make a unix stream closed explicit.

* Hack to debug linux process/stream.

* Revert to old linux pipe handling.

* Pass executable path for unit tests.
Split out CommandLine into own source.

* Small improvements in process/command line.

* Check process behavior with crash.

* Make stderr and stdout unbuffered for crash testing.

* Only turn disable buffering in crash test.

* Disable crash test on CI.

* Fix crash on clang/linux.

* Enable crash test.
Remove _appendBuffer as can use StreamUtil functionality.</content>
</entry>
<entry>
<title>Simplify CommandLine by removing Escaping (#1825)</title>
<updated>2021-04-29T19:45:25+00:00</updated>
<author>
<name>jsmall-nvidia</name>
<email>jsmall@nvidia.com</email>
</author>
<published>2021-04-29T19:45:25+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=ad6f3070251f25cf022c231b8567d78e98061127'/>
<id>urn:sha1:ad6f3070251f25cf022c231b8567d78e98061127</id>
<content type='text'>
* #include an absolute path didn't work - because paths were taken to always be relative.

* Split out StringEscapeUtil.

* Added StringEscapeUtil.

* Fix typo in unix quoting type.

* Small comment improvements.

* Try to fix linux linking issue.

* Fix typo.

* Attempt to fix linux link issue.

* Update VS proj even though nothing really changed.

* Fix another typo issue.

* Fix for windows issue.
Fixed bug.

* Make separate Utils for escaping.

* Fix typo.

* Split out into StringEscapeHandler.

* Windows shell does handle removing quotes (so remove code to remove them).

* Handle unescaping if not initiating using the shell.

* Slight improvement around shell like decoding.

* Simplify command extraction.

* Add shared-library category type.

* Fix bug in command extraction.

* Typo in transcendental category.

* Enable unit-test on in smoke test category.

* Make parsing failing output as a failing test.

* Fixes for transcendental tests. Disable tests that do not work.

* Changed category parsing.

* Removed the TestResult parameter from _gatherTestsForFile.
Made testsList only output.

* Remove testing if all tests were disabled.

* Make args of CommandLine always unescaped.

* Add category.

* Don't need escaping on unix/linux.

* Remove some no longer used functions.</content>
</entry>
<entry>
<title>Support for escaped paths in tools (#1823)</title>
<updated>2021-04-29T13:01:46+00:00</updated>
<author>
<name>jsmall-nvidia</name>
<email>jsmall@nvidia.com</email>
</author>
<published>2021-04-29T13:01:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=972bd3c4c24b06501c52127416afb763a066b8ad'/>
<id>urn:sha1:972bd3c4c24b06501c52127416afb763a066b8ad</id>
<content type='text'>
* #include an absolute path didn't work - because paths were taken to always be relative.

* Split out StringEscapeUtil.

* Added StringEscapeUtil.

* Fix typo in unix quoting type.

* Small comment improvements.

* Try to fix linux linking issue.

* Fix typo.

* Attempt to fix linux link issue.

* Update VS proj even though nothing really changed.

* Fix another typo issue.

* Fix for windows issue.
Fixed bug.

* Make separate Utils for escaping.

* Fix typo.

* Split out into StringEscapeHandler.

* Windows shell does handle removing quotes (so remove code to remove them).

* Handle unescaping if not initiating using the shell.

* Slight improvement around shell like decoding.

* Simplify command extraction.

* Add shared-library category type.

* Fix bug in command extraction.

* Typo in transcendental category.

* Enable unit-test on in smoke test category.

* Make parsing failing output as a failing test.

* Fixes for transcendental tests. Disable tests that do not work.

* Changed category parsing.

* Removed the TestResult parameter from _gatherTestsForFile.
Made testsList only output.

* Remove testing if all tests were disabled.

* Fix typo.

* Disable path canonical test on linux because CI issue.</content>
</entry>
<entry>
<title>Simple test profiling (#1062)</title>
<updated>2019-09-23T19:38:25+00:00</updated>
<author>
<name>jsmall-nvidia</name>
<email>jsmall@nvidia.com</email>
</author>
<published>2019-09-23T19:38:25+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=05af41d21d74d24871507e6f8f50574ea08c48a2'/>
<id>urn:sha1:05af41d21d74d24871507e6f8f50574ea08c48a2</id>
<content type='text'>
* First pass support for performance profiling

* Test across all elements

* Fix bug - sourceContents is not used, should use rawSource.

* * Add ability to get prelude from API.
* Allow specifying source language for render-test
* Made it possible to compile a test input file as C++
  * Special handling for reflection
* Added C++ impl to performance-profile.slang

* Remove some clang warnings.

* Output profile timings on appveyor and other TC.

* Remove passing around of StdWriters (can use global).
Small comment improvements.
</content>
</entry>
<entry>
<title>CPPCompiler improvements (#984)</title>
<updated>2019-06-14T16:20:12+00:00</updated>
<author>
<name>jsmall-nvidia</name>
<email>jsmall@nvidia.com</email>
</author>
<published>2019-06-14T16:20:12+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=8c56d83506ef92b15b15bdb5969008dd69c8d2a6'/>
<id>urn:sha1:8c56d83506ef92b15b15bdb5969008dd69c8d2a6</id>
<content type='text'>
* Removed the need for VisualStudio specific CPPCompiler
Improved the version parsing for gcc/clang
Removed need for slang-unix-cpp-compiler-util.cpp/.h
Remove binary before compiling in the compile c tests

* Moved VisualStudio calcArgs into CPPCompilerUtil - as code is not windows specific.

* Set up compile time version for gcc and clang

* Fix compilation on OSX - use remove instead of unlink for file deletion.

* On OSX - clang uses different string format.

* Removed /bin/sh invoking as not required for OSX.
</content>
</entry>
<entry>
<title>CommandLine arg escaping  (#980)</title>
<updated>2019-06-12T20:18:07+00:00</updated>
<author>
<name>jsmall-nvidia</name>
<email>jsmall@nvidia.com</email>
</author>
<published>2019-06-12T20:18:07+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=503721047731e8f6566bc51d6eadc7d24161c129'/>
<id>urn:sha1:503721047731e8f6566bc51d6eadc7d24161c129</id>
<content type='text'>
* Work in progress to be able to invoke VS from within code.

* First pass at windows version of refactor of OSProcessSpawner

* Closer to getting VS path lookup working.

* Make OSString assignable/ctor able

* Work out program files directory directly, so don't have to expand %%.

* WIP: Improve handling of process spawning.

* Add support for splitting input by line.

* * Correctly locates visual studio install
* Added functionality to invoke vs via cmd

* Add option to execute the command line.

* Handle in ProcessUtil for windows -&gt; WinHandle.

* Rename files slang-win-visual-studio-util.cpp/.h and slang-process-util.h

* First pass at unix/linux version of ProcessUtil.

* Fix reading Visual Studio path from the registry.

* Get compiling on linux with.

* Fix vcvarsall.bat name

* Use ProcessUtil to execute external code.

* Remove OSProcessSpawner.

* Remove includes for "os.h" where no longer needed.

* Fix tabbing issue in premake5.lua
Remove test code from slang-test-main.cpp

* Fix premake4.lua tabbing issue.

* Small fixes to slang-process-util.h
Init ExecuteResult on Win execute.

* Improve comments.

* Fix bug in StringUtil::calcLines - with oddly terminated source input being able to read past end.
Make slang-generate use StringUtil over it's own impl.

* Fix off by one bug in working out Visual Studio version.

* Fix bug in calculating Visual Studio Version

* Fix compilation on linux with string parameter being passed to messageFormat.

* Remove erroneous use of kOSError codes - use Result.

* First effort to generate standard compiler options.

* Initial efforts in compiling source code in test framework for VisualStudio.

* Testing compiling c code on VisualStudio on Windows.

* Fix warning on linux.

* Fix clang on linux warning (and therefore failing) returning a StringBuilder as String.

* Disable return-std-move on clang.

* CommandLine arguments are now tagged if they are escaped or not. That it is the clients responsibility to escape command lines that cannot be automatically escaped.

* Add checks on unix/linux that command line args are all unescaped.
</content>
</entry>
<entry>
<title>Visual Studio compilation working in test harness (#979)</title>
<updated>2019-06-12T18:28:16+00:00</updated>
<author>
<name>jsmall-nvidia</name>
<email>jsmall@nvidia.com</email>
</author>
<published>2019-06-12T18:28:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=7931adac99a78fd5488f665578fba858b34bc8a6'/>
<id>urn:sha1:7931adac99a78fd5488f665578fba858b34bc8a6</id>
<content type='text'>
* Work in progress to be able to invoke VS from within code.

* First pass at windows version of refactor of OSProcessSpawner

* Closer to getting VS path lookup working.

* Make OSString assignable/ctor able

* Work out program files directory directly, so don't have to expand %%.

* WIP: Improve handling of process spawning.

* Add support for splitting input by line.

* * Correctly locates visual studio install
* Added functionality to invoke vs via cmd

* Add option to execute the command line.

* Handle in ProcessUtil for windows -&gt; WinHandle.

* Rename files slang-win-visual-studio-util.cpp/.h and slang-process-util.h

* First pass at unix/linux version of ProcessUtil.

* Fix reading Visual Studio path from the registry.

* Get compiling on linux with.

* Fix vcvarsall.bat name

* Use ProcessUtil to execute external code.

* Remove OSProcessSpawner.

* Remove includes for "os.h" where no longer needed.

* Fix tabbing issue in premake5.lua
Remove test code from slang-test-main.cpp

* Fix premake4.lua tabbing issue.

* Small fixes to slang-process-util.h
Init ExecuteResult on Win execute.

* Improve comments.

* Fix bug in StringUtil::calcLines - with oddly terminated source input being able to read past end.
Make slang-generate use StringUtil over it's own impl.

* Fix off by one bug in working out Visual Studio version.

* Fix bug in calculating Visual Studio Version

* Fix compilation on linux with string parameter being passed to messageFormat.

* Remove erroneous use of kOSError codes - use Result.

* First effort to generate standard compiler options.

* Initial efforts in compiling source code in test framework for VisualStudio.

* Testing compiling c code on VisualStudio on Windows.

* Fix warning on linux.

* Fix clang on linux warning (and therefore failing) returning a StringBuilder as String.

* Disable return-std-move on clang.
</content>
</entry>
<entry>
<title>Runtime execution of Visual Studio Compiler (#978)</title>
<updated>2019-06-12T13:05:40+00:00</updated>
<author>
<name>jsmall-nvidia</name>
<email>jsmall@nvidia.com</email>
</author>
<published>2019-06-12T13:05:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=9d514e65f00dde0e309f33591f31fbf7f132a005'/>
<id>urn:sha1:9d514e65f00dde0e309f33591f31fbf7f132a005</id>
<content type='text'>
* Work in progress to be able to invoke VS from within code.

* First pass at windows version of refactor of OSProcessSpawner

* Closer to getting VS path lookup working.

* Make OSString assignable/ctor able

* Work out program files directory directly, so don't have to expand %%.

* WIP: Improve handling of process spawning.

* Add support for splitting input by line.

* * Correctly locates visual studio install
* Added functionality to invoke vs via cmd

* Add option to execute the command line.

* Handle in ProcessUtil for windows -&gt; WinHandle.

* Rename files slang-win-visual-studio-util.cpp/.h and slang-process-util.h

* First pass at unix/linux version of ProcessUtil.

* Fix reading Visual Studio path from the registry.

* Get compiling on linux with.

* Fix vcvarsall.bat name

* Use ProcessUtil to execute external code.

* Remove OSProcessSpawner.

* Remove includes for "os.h" where no longer needed.

* Fix tabbing issue in premake5.lua
Remove test code from slang-test-main.cpp

* Fix premake4.lua tabbing issue.

* Small fixes to slang-process-util.h
Init ExecuteResult on Win execute.

* Improve comments.

* Fix bug in StringUtil::calcLines - with oddly terminated source input being able to read past end.
Make slang-generate use StringUtil over it's own impl.

* Fix off by one bug in working out Visual Studio version.

* Fix bug in calculating Visual Studio Version

* Fix compilation on linux with string parameter being passed to messageFormat.

* Remove erroneous use of kOSError codes - use Result.
</content>
</entry>
</feed>
