From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30596 invoked by alias); 29 Jul 2013 08:46:45 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 30557 invoked by uid 89); 29 Jul 2013 08:46:45 -0000 X-Spam-SWARE-Status: No, score=-3.2 required=5.0 tests=AWL,BAYES_40,KHOP_RCVD_UNTRUST,KHOP_THREADED,RCVD_IN_HOSTKARMA_W,RCVD_IN_HOSTKARMA_WL,RDNS_NONE autolearn=no version=3.3.1 Received: from Unknown (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Mon, 29 Jul 2013 08:46:43 +0000 Received: from svr-orw-fem-01.mgc.mentorg.com ([147.34.98.93]) by relay1.mentorg.com with esmtp id 1V3j6C-0001Ji-4A from Yao_Qi@mentor.com for gdb-patches@sourceware.org; Mon, 29 Jul 2013 01:46:36 -0700 Received: from SVR-ORW-FEM-04.mgc.mentorg.com ([147.34.97.41]) by svr-orw-fem-01.mgc.mentorg.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675); Mon, 29 Jul 2013 01:46:35 -0700 Received: from qiyao.dyndns.org.dyndns.org (147.34.91.1) by svr-orw-fem-04.mgc.mentorg.com (147.34.97.41) with Microsoft SMTP Server id 14.2.247.3; Mon, 29 Jul 2013 01:46:35 -0700 From: Yao Qi To: Subject: [PATCH 1/3] Detect GDB is in cygwin Date: Mon, 29 Jul 2013 08:46:00 -0000 Message-ID: <1375087546-22591-2-git-send-email-yao@codesourcery.com> In-Reply-To: <1375087546-22591-1-git-send-email-yao@codesourcery.com> References: <1375087546-22591-1-git-send-email-yao@codesourcery.com> MIME-Version: 1.0 Content-Type: text/plain X-SW-Source: 2013-07/txt/msg00692.txt.bz2 Hello, This patch is to detect whether GDB is in cygwin by means of new added function 'is_in_cygwin'. In general, the detection is inspired by Corinna's example on detecting whether GDB is running in a cygwin pty. I extended the logic a little to handle the case we ssh to a cygwin machine without allocating a pty. In this patch, we'll find the file name of stdin, if its name is prefixed by "\cygwin-", we know GDB is running in cygwin. The C code is simple, but getting these simple c code compiled on various mingw compilers is not simple, due to different header files they shipped. I change configure.ac to first check winternl.h, if it is not found, check other needed headers. Then invoke AC_TRY_COMPILE to test whether I can use function NtQueryInformationFile. GDB is compiled with mingw32 gcc (Fedora MinGW 4.6.1-3.fc16) and x86_64-w64-mingw32-gcc (4.8.0 20121031). gdb: 2013-07-29 Yao Qi Corinna Vinschen * configure.ac: Invoke AC_CHECK_HEADERS to check winternl.h, ntdef.h, winbase.h and ddk/ntddk.h. * config.in: Re-generated. * configure: Re-generated. * defs.h [__MINGW32__] (is_in_cygwin_p): Declare. * mingw-hdep.c: Inlcude wchar.h. [HAVE_WINTERNL_H]: Include winternl.h. [!HAVE_WINTERNL_H] [HAVE_WINBASE_H]: Include ntdef.h. [!HAVE_WINTERNL_H] [HAVE_NTDEF_H]: winbase.h. [!HAVE_WINTERNL_H] [HAVE_DDK_NTDDK_H]ddk/ntddk.h. (pNtQueryInformationFile): Declare. [HAVE_NTQUERYINFORMATIONFILE] (get_filename_from_handle): New. (is_in_cygwin_p): New. --- gdb/config.in | 15 +++++++++ gdb/configure | 82 +++++++++++++++++++++++++++++++++++++++++++++++++ gdb/configure.ac | 40 ++++++++++++++++++++++++ gdb/defs.h | 4 ++ gdb/mingw-hdep.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 231 insertions(+), 0 deletions(-) diff --git a/gdb/config.in b/gdb/config.in index 92c2789..4fb45b4 100644 --- a/gdb/config.in +++ b/gdb/config.in @@ -84,6 +84,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_CURSES_H +/* Define to 1 if you have the header file. */ +#undef HAVE_DDK_NTDDK_H + /* Define to 1 if you have the declaration of `ADDR_NO_RANDOMIZE', and to 0 if you don't. */ #undef HAVE_DECL_ADDR_NO_RANDOMIZE @@ -270,6 +273,12 @@ /* Define to 1 if you have the header file. */ #undef HAVE_NLIST_H +/* Define to 1 if you have the header file. */ +#undef HAVE_NTDEF_H + +/* Define if function NtQueryInformationFile can be used. */ +#undef HAVE_NTQUERYINFORMATIONFILE + /* Define if you support the personality syscall. */ #undef HAVE_PERSONALITY @@ -572,6 +581,12 @@ /* Define to 1 if you have the `wborder' function. */ #undef HAVE_WBORDER +/* Define to 1 if you have the header file. */ +#undef HAVE_WINBASE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_WINTERNL_H + /* Define to 1 if `fork' works. */ #undef HAVE_WORKING_FORK diff --git a/gdb/configure b/gdb/configure index 4833297..2eb3bb8 100755 --- a/gdb/configure +++ b/gdb/configure @@ -9030,6 +9030,38 @@ fi done +# Check header winternl.h, if not found, check ntdef.h winbase.h and ddk/ntddk.h. +case "${host}" in + *-*-mingw*) for ac_header in winternl.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "winternl.h" "ac_cv_header_winternl_h" "$ac_includes_default" +if test "x$ac_cv_header_winternl_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_WINTERNL_H 1 +_ACEOF + +else + for ac_header in ntdef.h winbase.h ddk/ntddk.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +fi + +done + + ;; +esac + # ------------------------- # # Checks for declarations. # # ------------------------- # @@ -11962,6 +11994,56 @@ fi $as_echo "$found" >&6; } + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ + +#ifdef HAVE_WINTERNL_H +#include +#else + +#ifdef HAVE_WINBASE_H +#include +#endif +#ifdef HAVE_NTDEF_H +#include +#endif +#ifdef HAVE_DDK_NTDDK_H +#include +#endif + +#endif +HANDLE fh; +IO_STATUS_BLOCK io; +NTSTATUS status; +long buf[66]; + +NTSTATUS (NTAPI *pNtQueryInformationFile) (HANDLE, PIO_STATUS_BLOCK, PVOID, + ULONG, FILE_INFORMATION_CLASS); +pNtQueryInformationFile = (NTSTATUS (NTAPI *)(HANDLE, PIO_STATUS_BLOCK, + PVOID, ULONG, FILE_INFORMATION_CLASS)) + GetProcAddress (GetModuleHandle ("ntdll.dll"), "NtQueryInformationFile"); +pNtQueryInformationFile (fh, &io, pfni, sizeof buf, FileNameInformation); + + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + +$as_echo "#define HAVE_NTQUERYINFORMATIONFILE 1" >>confdefs.h + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + if test ${build} = ${host} -a ${host} = ${target} ; then case ${host_os} in solaris*) diff --git a/gdb/configure.ac b/gdb/configure.ac index 48f37c8..63284f3 100644 --- a/gdb/configure.ac +++ b/gdb/configure.ac @@ -1121,6 +1121,13 @@ AC_CHECK_HEADERS(term.h, [], [], #endif ]) +# Check header winternl.h, if not found, check ntdef.h winbase.h and ddk/ntddk.h. +case "${host}" in + *-*-mingw*) AC_CHECK_HEADERS(winternl.h, [], + [AC_CHECK_HEADERS(ntdef.h winbase.h ddk/ntddk.h, [], [],[])], []) + ;; +esac + # ------------------------- # # Checks for declarations. # # ------------------------- # @@ -1715,6 +1722,39 @@ fi AC_SUBST(RDYNAMIC) AC_MSG_RESULT($found) + + +AC_TRY_COMPILE([#include ], [ +#ifdef HAVE_WINTERNL_H +#include +#else + +#ifdef HAVE_WINBASE_H +#include +#endif +#ifdef HAVE_NTDEF_H +#include +#endif +#ifdef HAVE_DDK_NTDDK_H +#include +#endif + +#endif +HANDLE fh; +IO_STATUS_BLOCK io; +NTSTATUS status; +long buf[66]; + +NTSTATUS (NTAPI *pNtQueryInformationFile) (HANDLE, PIO_STATUS_BLOCK, PVOID, + ULONG, FILE_INFORMATION_CLASS); +pNtQueryInformationFile = (NTSTATUS (NTAPI *)(HANDLE, PIO_STATUS_BLOCK, + PVOID, ULONG, FILE_INFORMATION_CLASS)) + GetProcAddress (GetModuleHandle ("ntdll.dll"), "NtQueryInformationFile"); +pNtQueryInformationFile (fh, &io, pfni, sizeof buf, FileNameInformation); + +], [], +[AC_DEFINE(HAVE_NTQUERYINFORMATIONFILE, 1, [Define if function NtQueryInformationFile can be used.])]) + dnl For certain native configurations, we need to check whether thread dnl support can be built in or not. dnl diff --git a/gdb/defs.h b/gdb/defs.h index 014d7d4..b226157 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -790,6 +790,10 @@ enum block_enum FIRST_LOCAL_BLOCK = 2 }; +#ifdef __MINGW32__ +int is_in_cygwin_p (void); +#endif + #include "utils.h" #endif /* #ifndef DEFS_H */ diff --git a/gdb/mingw-hdep.c b/gdb/mingw-hdep.c index efc9848..2ba8017 100644 --- a/gdb/mingw-hdep.c +++ b/gdb/mingw-hdep.c @@ -28,6 +28,22 @@ #include "readline/readline.h" #include +#include + +#ifdef HAVE_WINTERNL_H +#include +#else +#ifdef HAVE_WINBASE_H +#include +#endif +#ifdef HAVE_NTDEF_H +#include +#endif +#ifdef HAVE_DDK_NTDDK_H +#include +#endif + +#endif /* HAVE_WINTERNL_H */ /* This event is signalled whenever an asynchronous SIGINT handler needs to perform an action in the main thread. */ @@ -265,6 +281,80 @@ gdb_call_async_signal_handler (struct async_signal_handler *handler, SetEvent (sigint_event); } +#if HAVE_NTQUERYINFORMATIONFILE + +/* Return the file name of handle FH. */ + +static PWCHAR +get_filename_from_handle (HANDLE fh) +{ + IO_STATUS_BLOCK io; + NTSTATUS status; + long buf[66]; /* NAME_MAX + 1 + sizeof ULONG */ + PFILE_NAME_INFORMATION pfni = (PFILE_NAME_INFORMATION) buf; + static NTSTATUS (NTAPI *pNtQueryInformationFile) (HANDLE, + PIO_STATUS_BLOCK, + PVOID, ULONG, + FILE_INFORMATION_CLASS); + + /* Calling the native NT function NtQueryInformationFile is required to + support pre-Vista systems. If that's of no concern, Vista introduced + the GetFileInformationByHandleEx call with the FileNameInfo info class, + which can be used instead. */ + if (!pNtQueryInformationFile) + { + pNtQueryInformationFile = (NTSTATUS (NTAPI *)(HANDLE, PIO_STATUS_BLOCK, + PVOID, ULONG, FILE_INFORMATION_CLASS)) + GetProcAddress (GetModuleHandle ("ntdll.dll"), + "NtQueryInformationFile"); + if (pNtQueryInformationFile == NULL) + return NULL; + } + if (!NT_SUCCESS (pNtQueryInformationFile (fh, &io, pfni, sizeof buf, + FileNameInformation))) + return NULL; + + /* The filename is not guaranteed to be NUL-terminated. */ + pfni->FileName[pfni->FileNameLength / sizeof (WCHAR)] = L'\0'; + + return pfni->FileName; +} + +#endif /* HAVE_NTQUERYINFORMATIONFILE */ + +/* Return true if GDB is running in Cygwin with or without pseudo-tty. */ + +int +is_in_cygwin_p (void) +{ + PWCHAR cp; + /* Now fetch the underlying HANDLE of stdin. */ + HANDLE fh = (HANDLE) _get_osfhandle (fileno (stdin)); + + if (!fh || fh == INVALID_HANDLE_VALUE) + return 0; + +#ifdef HAVE_NTQUERYINFORMATIONFILE + cp = get_filename_from_handle (fh); +#else + cp = NULL; +#endif + + /* Now check the name pattern. With pseudo-tty, the filename of + handle of stdin looks like this: + + \cygwin-c5e39b7a9d22bafb-{p,t}ty1-from-master + + Without pseudo-tty, the filename of handle of stdin looks like this: + + \cygwin-c5e39b7a9d22bafb-pipe-0x14C8-0x3 + + If the file name is prefixed with "\cygwin-", GDB is running in + cygwin. */ + + return (cp != NULL && wcsncmp (cp, L"\\cygwin-", 8) == 0); +} + /* -Wmissing-prototypes */ extern initialize_file_ftype _initialize_mingw_hdep; -- 1.7.7.6