Skip to content

Commit 720f4a8

Browse files
authored
Fix legacy app input from pipes on Windows. (KhronosGroup#749)
Was always broken for pipes created by Windows' shells (PowerShell and Command). Became broken in cygwin 3.4.x for pipes created by cygwin/MSYS2/Git for Windows shells when cygwin started mimicing the way Windows shells create pipes. The cause is that setting the `FILE_SYNCHRONOUS_IO_NONALERT` option when creating a pipe causes `cin.seekg(0)` on the pipe to return success when in fact seek is not supported. * Add launchDebugger function and --ld option to invoke it to `ktxApp` class and ktx tool as helpers for debugging pipes on Windows. These are only added when _WIN32 and DEBUG are defined.
1 parent 1a673f2 commit 720f4a8

File tree

2 files changed

+69
-5
lines changed

2 files changed

+69
-5
lines changed

utils/ktxapp.h

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66

77
#include "stdafx.h"
88

9+
#if defined (_WIN32)
10+
#define _CRT_SECURE_NO_WARNINGS
11+
#define WINDOWS_LEAN_AND_MEAN
12+
#include <windows.h>
13+
#endif
14+
915
#include <stdarg.h>
1016
#if (_MSVC_LANG >= 201703L || __cplusplus >= 201703L)
1117
#include <algorithm>
@@ -87,8 +93,12 @@ class ktxApp {
8793
virtual int main(int argc, _TCHAR* argv[]) = 0;
8894
virtual void usage() {
8995
cerr <<
90-
" -h, --help Print this usage message and exit.\n"
91-
" -v, --version Print the version number of this program and exit.\n";
96+
" -h, --help Print this usage message and exit.\n"
97+
" -v, --version Print the version number of this program and exit.\n"
98+
#if defined(_WIN32) && defined(DEBUG)
99+
" --ld Launch Visual Studio deugger at start up.\n"
100+
#endif
101+
;
92102
};
93103

94104
protected:
@@ -97,8 +107,9 @@ class ktxApp {
97107
_tstring outfile;
98108
int test;
99109
int warn;
110+
int launchDebugger;
100111

101-
commandOptions() : test(false), warn(1) { }
112+
commandOptions() : test(false), warn(1), launchDebugger(0) { }
102113
};
103114

104115
ktxApp(std::string& version, std::string& defaultVersion,
@@ -259,7 +270,7 @@ class ktxApp {
259270
listName.erase(0, relativize ? 2 : 1);
260271

261272
FILE *lf = nullptr;
262-
#ifdef _WIN32
273+
#if defined(_WIN32)
263274
_tfopen_s(&lf, listName.c_str(), "r");
264275
#else
265276
lf = _tfopen(listName.c_str(), "r");
@@ -352,6 +363,10 @@ class ktxApp {
352363
}
353364
}
354365
}
366+
#if defined(_WIN32) && defined(DEBUG)
367+
if (options.launchDebugger)
368+
launchDebugger();
369+
#endif
355370
}
356371

357372
virtual bool processOption(argparser& parser, int opt) = 0;
@@ -366,6 +381,47 @@ class ktxApp {
366381
cerr << endl;
367382
}
368383

384+
#if defined(_WIN32) && defined(DEBUG)
385+
// For use when debugging stdin with Visual Studio which does not have a
386+
// "wait for executable to be launched" choice in its debugger settings.
387+
bool launchDebugger()
388+
{
389+
// Get System directory, typically c:\windows\system32
390+
std::wstring systemDir(MAX_PATH + 1, '\0');
391+
UINT nChars = GetSystemDirectoryW(&systemDir[0],
392+
static_cast<UINT>(systemDir.length()));
393+
if (nChars == 0) return false; // failed to get system directory
394+
systemDir.resize(nChars);
395+
396+
// Get process ID and create the command line
397+
DWORD pid = GetCurrentProcessId();
398+
std::wostringstream s;
399+
s << systemDir << L"\\vsjitdebugger.exe -p " << pid;
400+
std::wstring cmdLine = s.str();
401+
402+
// Start debugger process
403+
STARTUPINFOW si;
404+
ZeroMemory(&si, sizeof(si));
405+
si.cb = sizeof(si);
406+
407+
PROCESS_INFORMATION pi;
408+
ZeroMemory(&pi, sizeof(pi));
409+
410+
if (!CreateProcessW(NULL, &cmdLine[0], NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) return false;
411+
412+
// Close debugger process handles to eliminate resource leak
413+
CloseHandle(pi.hThread);
414+
CloseHandle(pi.hProcess);
415+
416+
// Wait for the debugger to attach
417+
while (!IsDebuggerPresent()) Sleep(100);
418+
419+
// Stop execution so the debugger can take over
420+
DebugBreak();
421+
return true;
422+
}
423+
#endif
424+
369425
_tstring name;
370426
_tstring& version;
371427
_tstring& defaultVersion;
@@ -378,6 +434,9 @@ class ktxApp {
378434
{ "help", argparser::option::no_argument, NULL, 'h' },
379435
{ "version", argparser::option::no_argument, NULL, 'v' },
380436
{ "test", argparser::option::no_argument, &options.test, 1},
437+
#if defined(_WIN32) && defined(DEBUG)
438+
{ "ld", argparser::option::no_argument, &options.launchDebugger, 1},
439+
#endif
381440
// -NSDocumentRevisionsDebugMode YES is appended to the end
382441
// of the command by Xcode when debugging and "Allow debugging when
383442
// using document Versions Browser" is checked in the scheme. It

utils/stdafx.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@
55

66
#pragma once
77

8-
#define _CRT_SECURE_NO_WARNINGS // For _WIN32. Must be before <stdio.h>.
8+
#if defined(_WIN32)
9+
// _CRT_SECURE_NO_WARNINGS must be defined before <windows.h>,
10+
// <stdio.h> and and <iostream>
11+
#define _CRT_SECURE_NO_WARNINGS
12+
#endif
13+
914
#include <assert.h>
1015
#include <stdio.h>
1116
#ifdef _WIN32

0 commit comments

Comments
 (0)