Re: [PATCH v4 1/1] Cygwin: pty: Fix state management for pseudo console support.

2019-09-03 Thread Takashi Yano
Hi Corinna,

I have posted several patches for PTY with pseudo console support.
Please apply them in the following order.

[PATCH 1/4] Cygwin: pty: Code cleanup
- Cleanup the code which is commented out by #if 0 regarding pseudo
  console.
- Remove #if 1 for experimental code which seems to be stable.

[PATCH 2/4] Cygwin: pty: Speed up a little hooked Win32 API for pseudo console.
- Some Win32 APIs are hooked in pty code for pseudo console support.
  This causes slow down. This patch improves speed a little.

[PATCH 3/4] Cygwin: pty: Move function hook_api() into hookapi.cc.
- PTY uses Win32 API hook for pseudo console suppot. The function
  hook_api() is used for this purpose and defined in fhandler_tty.cc
  previously. This patch moves it into hookapi.cc.

[PATCH 4/4] Cygwin: pty: Limit API hook to the program linked with the APIs.
- API hook used for pseudo console support causes slow down.
  This patch limits API hook to only program which is linked
  with the corresponding APIs. Normal cygwin program is not
  linked with such APIs (such as WriteFile, etc...) directly,
  therefore, no slow down occurs. However, console access by
  cygwin.dll itself cannot switch the r/w pipe to pseudo console
  side. Therefore, the code to switch it forcely to pseudo
  console side is added to smallprint.cc and strace.cc.

[PATCH v5 1/1] Cygwin: pty: Fix state management for pseudo console support.
- Pseudo console support introduced by commit
  169d65a5774acc76ce3f3feeedcbae7405aa9b57 has some bugs which
  cause mismatch between state variables and real pseudo console
  state regarding console attaching and r/w pipe switching. This
  patch fixes this issue by redesigning the state management.

This hopefully fixes the problem 3 in
https://cygwin.com/ml/cygwin/2019-08/msg00401.html
This also fixes the first problem regarding "Bad file descriptor" error
reported in
https://cygwin.com/ml/cygwin-patches/2019-q3/msg00104.html

[PATCH 1/2] Cygwin: pty: Add a workaround for ^C handling.
- Pseudo console support introduced by commit
  169d65a5774acc76ce3f3feeedcbae7405aa9b57 sometimes cause random
  crash or freeze by pressing ^C while cygwin and non-cygwin
  processes are executed simultaneously in the same pty. This
  patch is a workaround for this issue.

[PATCH 2/2] Cygwin: pty: Disable clear screen on new pty if TERM=dumb or emacs*.
- Pseudo console support introduced by commit
  169d65a5774acc76ce3f3feeedcbae7405aa9b57 shows garbage ^[[H^[[J in
  some of emacs screens. These screens do not handle ANSI escape
  sequences. Therefore, clear screen is disabled on these screens.

This fixes the second problem on emacs reported in
https://cygwin.com/ml/cygwin-patches/2019-q3/msg00104.html

On Tue, 3 Sep 2019 11:16:38 +0200
Corinna Vinschen wrote:
> This is a slowdown of about 15%.  That's quite a lot.  Can't you just
> check the incoming handle against the interesting handles somehow?
> If there's no other way around it, we should at least make sure (in a
> separate patch) that Cygwin calls NtReadFile/NtWriteFile throughout,
> except in tty and console code.

I came up with an idea, and implemented it. As described obove,
Win32 APIs are not hooked any more in normal cygwin process.
Hook is done only if the program is directly linked with corresponding
APIs. However, this strategy does not have the effect for console
access by cygwin1.dll itself. So, to switch r/w pipe to pseudo console
side, I added the code in strace.cc and smallprint.cc.

Could you please have a look?

-- 
Takashi Yano 


Re: [PATCH v4 1/1] Cygwin: pty: Fix state management for pseudo console support.

2019-09-03 Thread Corinna Vinschen
Hi Takashi,

On Sep  3 12:05, Takashi Yano wrote:
> > > -  Sleep (60); /* Wait for pty_master_fwd_thread() */
> > > +  Sleep (20); /* Wait for pty_master_fwd_thread() */
> > 
> > Isn't that a separate issue as well?  A separate patch may be in order
> > here, kind of like "Cygwin: pseudo console: reduce time sleeping ..."
> > with a short description why that makes sense?
> 
> Actually it is not. The wait time became able to be reduced by
> redesigning switching of r/w pipes which managed via variable
> switch_to_pcon. So I think this should be included in this patch. 

Ok.

> > However, I have a few questions in terms of the code in general, namely
> > in terms of
> > 
> >   ALWAYS_USE_PCON
> >   USE_API_HOOK
> >   USE_OWN_NLS_FUNC
> > 
> > Can you describe again why you introduced these macros?
> 
> These are defined for debugging purpose.
> 
> If ALWAYS_USE_PCON is defined to true, pseudo console pipe is used for
> all process including pure cygwin process. Usually, this should be false
> so that the cygwin process use named pipe as previous.
> 
> USE_API_HOOK is for enabling/disabling the API hook to detect direct
> console access in cygwin process. This should be true so that the
> r/w pipe switching is set to pseudo console side for the cygwin
> process which directly access console.
> 
> As for USE_OWN_NLS_FUNC, I have not decided yet which codes should be
> used. If USE_OWN_NLS_FUNC is false, setlocale (LC_CTYPE, "") is
> called therefore it may affect to some programs wihch do not call
> setlocale().
> 
> > In terms of USE_API_HOOK:
> > 
> > - Shouldn't the hook_api function be moved to hookapi.cc?
> 
> I will move it into hookapi.cc, and post it as a separate patch.
> 
> > - Do we really want to hook every invocation of WriteFile/ReadFile?
> >   Doesn't that potentially slow down an exec'ed process a lot?
> >   We're still not using the NT functions throughout outside of the
> >   console/tty code.
> 
> I measured the time for calling WriteFile() 100 times writing
> 1 byte to a disk file for each call.

Files are not affected in Cygwin, fortunately.  They use
NtReadFile/NtWriteFile, not ReadFile/WriteFile.  However, other
stuff is still affected...

> Not hooked:
> Total: 4.558321 seconsd
> 
> Hooked:
> Total: 6.522692 seconsd
> 
> Hooking causes slow down indeed. It seems that GetConsoleMode()
> is slow. So I have added the check for GetFileType() before
> GetConsoleMode() and made check in two stages.
> 
> Hooked (new):
> Total: 5.217996 seconsd
> 
> This results in speed up a little. I will post another patch for this.

This is a slowdown of about 15%.  That's quite a lot.  Can't you just
check the incoming handle against the interesting handles somehow?
If there's no other way around it, we should at least make sure (in a
separate patch) that Cygwin calls NtReadFile/NtWriteFile throughout,
except in tty and console code.

> > In terms of USE_OWN_NLS_FUNC:
> > 
> > - Why do we need this function at all?  Can't this be handled by
> >   __loadlocale instead?  If not, what is __loadlocale missing to make
> >   this work without duplicating the function?
> 
> Calling __loadlocale() here causes execution error.
> 
> mintty:
>   0 [main] tcsh 1901 sig_send: error sending signal 6, pid 1901, pipe 
> handle 0x0, nb 0, packsize 164, Win32 error 6
> 
> script:
> Script started, file is typescript
> script: failed to execute /bin/tcsh: Bad address
> Script done, file is typescript
> 
> I could not find out the reason. Some kind of initialization which
> is needed by __loadlocale() may not be done yet. So I copied
> only necessary part from __loadlocale() and nl_langinfo().
> 
> Simply,
>  path_conv a ("/usr/share/locale/locale.alias");
> also causes errors on starting mintty.
> 
> Ideally, the cause of the error should be found out, I suppose.

Indeed.  We can keep the code in for now, but the end result should
call a tweaked version of __loadlocale instead.  As long as the 
tweak only requires a single extra argument, or if the category or
new_locale argument can be used as indicator to trigger the required
special behavour, we should have no problem to get that into newlib.


Thanks,
Corinna

-- 
Corinna Vinschen
Cygwin Maintainer


signature.asc
Description: PGP signature


Re: [PATCH v4 1/1] Cygwin: pty: Fix state management for pseudo console support.

2019-09-02 Thread Takashi Yano
Hi Corinna,

On Mon, 2 Sep 2019 16:37:16 +0200
Corinna Vinschen wrote:
> >  class fhandler_pty_slave: public fhandler_pty_common
> >  {
> >HANDLE inuse;// used to indicate that a tty is in use
> >HANDLE output_handle_cyg, io_handle_cyg;
> > +  DWORD pidRestore;
> 
> Please don't use camelback.  s/pidRestore/pid_restore/g

I will fix it in v5 patch.

> > - HeapAlloc (GetProcessHeap (), 0, num * sizeof (DWORD));
> > -  num = GetConsoleProcessList (list, num);
> > + HeapAlloc (GetProcessHeap (), 0, (num + 16) * sizeof (DWORD));
> > +  num = GetConsoleProcessList (list, num + 16);
> 
> You're still going to change that, right?

This is temporary code while debugging. Sorry. I will fix it in v5.

> > @@ -855,26 +868,6 @@ fhandler_pty_slave::cleanup ()
> >  int
> >  fhandler_pty_slave::close ()
> >  {
> > -#if 0
> > -  if (getPseudoConsole ())
> > -{
> > -  INPUT_RECORD inp[128];
> > -  DWORD n;
> > -  PeekFunc =
> > -   PeekConsoleInputA_Orig ? PeekConsoleInputA_Orig : PeekConsoleInput;
> > -  PeekFunc (get_handle (), inp, 128, );
> > -  bool pipe_empty = true;
> > -  while (n-- > 0)
> > -   if (inp[n].EventType == KEY_EVENT && inp[n].Event.KeyEvent.bKeyDown)
> > - pipe_empty = false;
> > -  if (pipe_empty)
> > -   {
> > - /* Flush input buffer */
> > - size_t len = UINT_MAX;
> > - read (NULL, len);
> > -   }
> > -}
> > -#endif
> 
> Ideally stuff like that should be in a separate code cleanup patch.

I see. I will post it as a separate patch.

> > -  Sleep (60); /* Wait for pty_master_fwd_thread() */
> > +  Sleep (20); /* Wait for pty_master_fwd_thread() */
> 
> Isn't that a separate issue as well?  A separate patch may be in order
> here, kind of like "Cygwin: pseudo console: reduce time sleeping ..."
> with a short description why that makes sense?

Actually it is not. The wait time became able to be reduced by
redesigning switching of r/w pipes which managed via variable
switch_to_pcon. So I think this should be included in this patch. 

> > + /* If not attached this pseudo console, try to attach temporarily. */
>
> to

Thanks.

> > - get_ttyp ()->hPseudoConsole = NULL;
> > + //get_ttyp ()->hPseudoConsole = NULL; // Do not clear for safty.
> 
> Why don't you just drop the line?

OK. Just drop it.

> Other than that, the patch looks good.
> 
> However, I have a few questions in terms of the code in general, namely
> in terms of
> 
>   ALWAYS_USE_PCON
>   USE_API_HOOK
>   USE_OWN_NLS_FUNC
> 
> Can you describe again why you introduced these macros?

These are defined for debugging purpose.

If ALWAYS_USE_PCON is defined to true, pseudo console pipe is used for
all process including pure cygwin process. Usually, this should be false
so that the cygwin process use named pipe as previous.

USE_API_HOOK is for enabling/disabling the API hook to detect direct
console access in cygwin process. This should be true so that the
r/w pipe switching is set to pseudo console side for the cygwin
process which directly access console.

As for USE_OWN_NLS_FUNC, I have not decided yet which codes should be
used. If USE_OWN_NLS_FUNC is false, setlocale (LC_CTYPE, "") is
called therefore it may affect to some programs wihch do not call
setlocale().

> In terms of USE_API_HOOK:
> 
> - Shouldn't the hook_api function be moved to hookapi.cc?

I will move it into hookapi.cc, and post it as a separate patch.

> - Do we really want to hook every invocation of WriteFile/ReadFile?
>   Doesn't that potentially slow down an exec'ed process a lot?
>   We're still not using the NT functions throughout outside of the
>   console/tty code.

I measured the time for calling WriteFile() 100 times writing
1 byte to a disk file for each call.

Not hooked:
Total: 4.558321 seconsd

Hooked:
Total: 6.522692 seconsd

Hooking causes slow down indeed. It seems that GetConsoleMode()
is slow. So I have added the check for GetFileType() before
GetConsoleMode() and made check in two stages.

Hooked (new):
Total: 5.217996 seconsd

This results in speed up a little. I will post another patch for this.

> In terms of USE_OWN_NLS_FUNC:
> 
> - Why do we need this function at all?  Can't this be handled by
>   __loadlocale instead?  If not, what is __loadlocale missing to make
>   this work without duplicating the function?

Calling __loadlocale() here causes execution error.

mintty:
  0 [main] tcsh 1901 sig_send: error sending signal 6, pid 1901, pipe 
handle 0x0, nb 0, packsize 164, Win32 error 6

script:
Script started, file is typescript
script: failed to execute /bin/tcsh: Bad address
Script done, file is typescript

I could not find out the reason. Some kind of initialization which
is needed by __loadlocale() may not be done yet. So I copied
only necessary part from __loadlocale() and nl_langinfo().

Simply,
 path_conv a ("/usr/share/locale/locale.alias");
also causes errors 

Re: [PATCH v4 1/1] Cygwin: pty: Fix state management for pseudo console support.

2019-09-02 Thread Corinna Vinschen
On Sep  2 07:11, Takashi Yano wrote:
> - Pseudo console support introduced by commit
>   169d65a5774acc76ce3f3feeedcbae7405aa9b57 has some bugs which
>   cause mismatch between state variables and real pseudo console
>   state regarding console attaching and r/w pipe switching. This
>   patch fixes this issue by redesigning the state management.
> ---
>  winsup/cygwin/dtable.cc   |  15 +-
>  winsup/cygwin/fhandler.h  |   6 +-
>  winsup/cygwin/fhandler_console.cc |   6 +-
>  winsup/cygwin/fhandler_tty.cc | 415 --
>  winsup/cygwin/fork.cc |  24 +-
>  winsup/cygwin/spawn.cc|  65 +++--
>  6 files changed, 289 insertions(+), 242 deletions(-)
> [...]
>  class fhandler_pty_slave: public fhandler_pty_common
>  {
>HANDLE inuse;  // used to indicate that a tty is in use
>HANDLE output_handle_cyg, io_handle_cyg;
> +  DWORD pidRestore;

Please don't use camelback.  s/pidRestore/pid_restore/g

> -   HeapAlloc (GetProcessHeap (), 0, num * sizeof (DWORD));
> -  num = GetConsoleProcessList (list, num);
> +   HeapAlloc (GetProcessHeap (), 0, (num + 16) * sizeof (DWORD));
> +  num = GetConsoleProcessList (list, num + 16);

You're still going to change that, right?

> @@ -855,26 +868,6 @@ fhandler_pty_slave::cleanup ()
>  int
>  fhandler_pty_slave::close ()
>  {
> -#if 0
> -  if (getPseudoConsole ())
> -{
> -  INPUT_RECORD inp[128];
> -  DWORD n;
> -  PeekFunc =
> - PeekConsoleInputA_Orig ? PeekConsoleInputA_Orig : PeekConsoleInput;
> -  PeekFunc (get_handle (), inp, 128, );
> -  bool pipe_empty = true;
> -  while (n-- > 0)
> - if (inp[n].EventType == KEY_EVENT && inp[n].Event.KeyEvent.bKeyDown)
> -   pipe_empty = false;
> -  if (pipe_empty)
> - {
> -   /* Flush input buffer */
> -   size_t len = UINT_MAX;
> -   read (NULL, len);
> - }
> -}
> -#endif

Ideally stuff like that should be in a separate code cleanup patch.

> -  Sleep (60); /* Wait for pty_master_fwd_thread() */
> +  Sleep (20); /* Wait for pty_master_fwd_thread() */

Isn't that a separate issue as well?  A separate patch may be in order
here, kind of like "Cygwin: pseudo console: reduce time sleeping ..."
with a short description why that makes sense?

> +   /* If not attached this pseudo console, try to attach temporarily. */
   
to

> -   get_ttyp ()->hPseudoConsole = NULL;
> +   //get_ttyp ()->hPseudoConsole = NULL; // Do not clear for safty.

Why don't you just drop the line?

Other than that, the patch looks good.

However, I have a few questions in terms of the code in general, namely
in terms of

  ALWAYS_USE_PCON
  USE_API_HOOK
  USE_OWN_NLS_FUNC

Can you describe again why you introduced these macros?

In terms of USE_API_HOOK:

- Shouldn't the hook_api function be moved to hookapi.cc?

- Do we really want to hook every invocation of WriteFile/ReadFile?
  Doesn't that potentially slow down an exec'ed process a lot?
  We're still not using the NT functions throughout outside of the
  console/tty code.

In terms of USE_OWN_NLS_FUNC:

- Why do we need this function at all?  Can't this be handled by
  __loadlocale instead?  If not, what is __loadlocale missing to make
  this work without duplicating the function?


Thanks,
Corinna

-- 
Corinna Vinschen
Cygwin Maintainer


signature.asc
Description: PGP signature