You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
powershell .\sd-cli.exe --diffusion-model nonexistent_model.gguf --prompt test --output test.png > output.log 2>&1
Or using Out-File: powershell .\sd-cli.exe --diffusion-model nonexistent_model.gguf --prompt test --output test.png *> output.log
Steps to reproduce
Run sd-cli.exe with output redirected to a file using PowerShell redirection (>, *>, or Out-File)
Check the captured output file
Compare with direct console output (without redirection)
What you expected to happen
When redirecting output to a file, all log messages should be captured, including both log level tags ([INFO], [WARN], [ERROR]) and the actual log content (error messages, status information, etc.), just like when running directly in the console.
What actually happened
When redirecting output to a file, only log level tags are captured, while the actual log content is lost.
Captured output when redirected (only tags, no content):
Before this PR: Used fprintf(). Output could be captured via redirection, but UTF-8 characters displayed incorrectly.
After this PR: Uses print_utf8() which calls WriteConsoleW(). UTF-8 characters display correctly, but output cannot be captured via redirection (regression).
Root Cause:
The call chain: stable-diffusion.cpp (LOG_INFO/LOG_ERROR) calls util.cpp (log_printf), which calls sd_log_cb (CLI callback), which calls log_print, which calls print_utf8.
Part 1: Log tags ([INFO], [ERROR], etc.) are written via fprintf(). Can be captured because it uses stdout/stderr streams.
Part 2: Log content (actual messages) are written via print_utf8() which calls WriteConsoleW(). Cannot be captured because it bypasses stdout/stderr and writes directly to console.
Why tags work but content doesn't:
Log tags ([INFO], [ERROR], etc.) are written via fprintf(out_stream, "[%-5s] ", level_str):
WriteConsoleW() writes directly to the console buffer, bypassing stdout/stderr streams.
When stdout/stderr are redirected, WriteConsoleW still writes to the console, not to the redirected destination.
Result: Only the log level tags (written via fprintf) are captured, but the actual content (written via WriteConsoleW) is lost.
Additional context / environment details
Impact
Regression: Output that was previously capturable (via fprintf) is now lost
Affects: All applications that need to capture sd-cli.exe output:
Electron applications
CI/CD scripts
Log collection tools
Automated testing frameworks
References
Microsoft Documentation:
WriteConsole function - "The WriteConsole function can only be used with a console handle. If a standard handle has been redirected and is no longer a console handle, WriteConsole will fail."
Git commit
bda7fab
Operating System & Version
windows 11 25H2 (Build 26220)
GGML backends
CUDA
Command-line arguments used
powershell .\sd-cli.exe --diffusion-model nonexistent_model.gguf --prompt test --output test.png > output.log 2>&1Or using
Out-File:powershell .\sd-cli.exe --diffusion-model nonexistent_model.gguf --prompt test --output test.png *> output.logSteps to reproduce
sd-cli.exewith output redirected to a file using PowerShell redirection (>,*>, orOut-File)What you expected to happen
When redirecting output to a file, all log messages should be captured, including both log level tags (
[INFO],[WARN],[ERROR]) and the actual log content (error messages, status information, etc.), just like when running directly in the console.What actually happened
When redirecting output to a file, only log level tags are captured, while the actual log content is lost.
Captured output when redirected (only tags, no content):
Output when run directly in console (complete with content):
Comparison:
Logs / error messages / stack trace
This is a regression introduced in #1101 (commit
ebe9d26, Dec 16, 2025).Problem Analysis:
Background:
print_utf8()function to fix UTF-8 character encoding issues on Windowsfprintf(). Output could be captured via redirection, but UTF-8 characters displayed incorrectly.print_utf8()which callsWriteConsoleW(). UTF-8 characters display correctly, but output cannot be captured via redirection (regression).Root Cause:
stable-diffusion.cpp(LOG_INFO/LOG_ERROR) callsutil.cpp(log_printf), which callssd_log_cb(CLI callback), which callslog_print, which callsprint_utf8.util.cpp:278(log_printf function):stable-diffusion.cpp/util.cpp
Lines 278 to 298 in 97cf2ef
examples/cli/main.cpp:274(sd_log_cb callback):stable-diffusion.cpp/examples/cli/main.cpp
Lines 272 to 275 in 97cf2ef
print_utf8()function inexamples/common/common.hppunconditionally usesWriteConsoleW:stable-diffusion.cpp/examples/common/common.hpp
Lines 89 to 112 in 97cf2ef
log_print()function splits output into two parts:stable-diffusion.cpp/examples/common/common.hpp
Lines 126 to 165 in 97cf2ef
[INFO],[ERROR], etc.) are written viafprintf(). Can be captured because it uses stdout/stderr streams.print_utf8()which callsWriteConsoleW(). Cannot be captured because it bypasses stdout/stderr and writes directly to console.[INFO],[ERROR], etc.) are written viafprintf(out_stream, "[%-5s] ", level_str):stable-diffusion.cpp/examples/common/common.hpp
Line 161 in 97cf2ef
fprintf()writes to the FILE* stream (stdout/stderr), which can be redirected. This is a standard C library function that respects stream redirection.print_utf8(out_stream, log):stable-diffusion.cpp/examples/common/common.hpp
Line 163 in 97cf2ef
WriteConsoleW():stable-diffusion.cpp/examples/common/common.hpp
Line 106 in 97cf2ef
WriteConsoleW()writes directly to the console buffer, bypassing stdout/stderr streams.WriteConsoleWstill writes to the console, not to the redirected destination.fprintf) are captured, but the actual content (written viaWriteConsoleW) is lost.Additional context / environment details
Impact
fprintf) is now lostsd-cli.exeoutput:References
Microsoft Documentation:
WriteConsolefunction can only be used with a console handle. If a standard handle has been redirected and is no longer a console handle,WriteConsolewill fail."Related Discussions: