From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 105251 invoked by alias); 6 Jun 2016 10:12:57 -0000 Mailing-List: contact cygwin-help@cygwin.com; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner@cygwin.com Mail-Followup-To: cygwin@cygwin.com Received: (qmail 105239 invoked by uid 89); 6 Jun 2016 10:12:55 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.6 required=5.0 tests=AWL,BAYES_00,SPF_PASS autolearn=ham version=3.3.2 spammy=earth, H*c:MultipHrt, 2.5.1, Hx-languages-length:8024 X-HELO: conuserg-06.nifty.com Received: from conuserg-06.nifty.com (HELO conuserg-06.nifty.com) (210.131.2.73) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (DES-CBC3-SHA encrypted) ESMTPS; Mon, 06 Jun 2016 10:12:44 +0000 Received: from Express5800-S70 (ntsitm172155.sitm.nt.ftth.ppp.infoweb.ne.jp [211.133.44.155]) (authenticated) by conuserg-06.nifty.com with ESMTP id u56ACNc4024754 for ; Mon, 6 Jun 2016 19:12:23 +0900 DKIM-Filter: OpenDKIM Filter v2.10.3 conuserg-06.nifty.com u56ACNc4024754 X-Nifty-SrcIP: [211.133.44.155] Date: Mon, 06 Jun 2016 10:12:00 -0000 From: Takashi Yano To: cygwin@cygwin.com Subject: Re: gdb pty problem [Was: emacs gud-interface is not updated after gdb command execution (maybe because of incomplete output from gdb)] Message-Id: <20160606191231.a60b226a9867c15023e07fb1@nifty.ne.jp> In-Reply-To: <20160601141820.GF11431@calimero.vinschen.de> References: <466943424.37628.394d161a-7219-415d-a659-0f774811ad2d.open-xchange@email.1und1.de> <44459aa0-4381-2368-ab63-5dffc26f3344@cornell.edu> <20160531094115.GE24015@calimero.vinschen.de> <34c9cf10-4930-a017-92fc-fd56171671b1@cornell.edu> <20160601141820.GF11431@calimero.vinschen.de> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="Multipart=_Mon__6_Jun_2016_19_12_31_+0900_Dvs56MeAlzKVfQ6l" X-IsSubscribed: yes X-SW-Source: 2016-06/txt/msg00056.txt.bz2 --Multipart=_Mon__6_Jun_2016_19_12_31_+0900_Dvs56MeAlzKVfQ6l Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-length: 6980 Hi Corinna, I had looked into this problem, and found the cause. 'man termios' says: "A read(2) returns at most one line of input" in canonical mode. On cygwin 2.5.1, read(2) returns all data in buffer if the buffer size specified is large enough. This behaviour is correct in noncanonical mode, but is not correct in canonical mode. So, I would like to propose a following patch. diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 6c00d61..733644f 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -756,10 +756,6 @@ fhandler_pty_slave::read (void *ptr, size_t& len) goto out; } - /* On first peek determine no. of bytes to flush. */ - if (!ptr && len == UINT_MAX) - len = (size_t) bytes_in_pipe; - if (ptr && !bytes_in_pipe && !vmin && !time_to_wait) { ReleaseMutex (input_mutex); @@ -767,7 +763,9 @@ fhandler_pty_slave::read (void *ptr, size_t& len) return; } - readlen = MIN (bytes_in_pipe, MIN (len, sizeof (buf))); + readlen = bytes_in_pipe ? MIN (len, sizeof (buf)) : 0; + if (get_ttyp ()->ti.c_lflag & ICANON && ptr) + readlen = MIN (bytes_in_pipe, readlen); #if 0 /* Why on earth is the read length reduced to vmin, even if more bytes @@ -804,7 +802,8 @@ fhandler_pty_slave::read (void *ptr, size_t& len) } if (n) { - len -= n; + if (!(!ptr && len == UINT_MAX)) /* not tcflush() */ + len -= n; totalread += n; if (ptr) { While checking this problem, I found a bug of tcflush(). tcflush() flushes only partial data in the buffer. The patch above also fixes this bug. A test case attached (pty_readlen.c) is for confirming the behaviour of read() and tcflush(). Test results are as follows. debian GNU/Linux: ---------- 01234 ---------- 56789 ABCDE ---------- ---------- cygwin 2.5.1: ---------- 01234 56789 ---------- ABCDE ---------- KLMNO ---------- cygwin 2.5.2 (git head): ---------- 01234 ---------- 56789 ---------- FGHIJ ---------- cygwin with a patch I propose: ---------- 01234 ---------- 56789 ABCDE ---------- ---------- Of course, Ken's gdbstc works fine without sleep with this patch, as well as original emacs case. On Wed, 1 Jun 2016 16:18:20 +0200 Corinna Vinschen wrote: > Hi Takashi, > > > can you please have a look? > > > Thanks, > Corinna > > > On Jun 1 08:51, Ken Brown wrote: > > On 5/31/2016 5:41 AM, Corinna Vinschen wrote: > > > Any chance you could bisect Cygwin to help finding the culprit? > > > > The culprit is > > > > commit 252a07b0ad3353abcd0fcd9b1b65ff977acd679e > > Author: Takashi Yano > > Date: Fri Apr 3 13:07:35 2015 +0900 > > > > Cygwin hangs up if several keys are typed during outputting a lot of texts. > > > > * fhandler_tty.cc (fhandler_pty_slave::read): Change calculation of > > "readlen" not to use "bytes_in_pipe" value directly. > > > > > > Reverting that commit fixes the problem. To test, compile and run the attached file. > > > > $ gcc gdbstc.cc > > > > $ ./a > > 1-inferior-tty-set /dev/pty3 > > 2-gdb-set height 0 > > 3-gdb-set non-stop 1 > > 4-file-list-exec-source-files > > 5-file-list-exec-source-file > > 6-gdb-show prompt > > 7-stack-info-frame > > 8-thread-info > > 9-break-list > > q > > *** using gdb > > =thread-group-added,id="i1" > > ~"GNU gdb (GDB) (Cygwin 7.10.1-1) 7.10.1\n" > > ~"Copyright (C) 2015 Free Software Foundation, Inc.\n" > > ~"License GPLv3+: GNU GPL version 3 or later \nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to the extent permitted by law. Type \"show copying\"\nand \"show warranty\" for details.\n" > > ~"This GDB was configured as \"i686-pc-cygwin\".\nType \"show configuration\" for configuration details." > > ~"\nFor bug reporting instructions, please see:\n" > > ~".\n" > > ~"Find the GDB manual and other documentation resources online at:\n.\n" > > ~"For help, type \"help\".\n" > > ~"Type \"apropos word\" to search for commands related to \"word\".\n" > > =cmd-param-changed,param="auto-load safe-path",value="/" > > (gdb) > > ... > > > > In bad cases (bug present), the program hangs and doesn't complete until the gdb process is killed from a different terminal. In good cases it runs to completion. > > > > Ken > > > #include > > #include > > #include > > #include > > #include > > #include > > > > void get_output (int fd); > > > > int > > main (int argc, const char **argv) > > { > > int master; > > pid_t pid; > > > > if ((pid = forkpty (&master, NULL, NULL, NULL)) < 0) > > { > > perror ("forkpty"); > > exit (1); > > } > > /* child */ > > if (pid == 0) > > { > > const char *av[100]; > > // putenv ("HOME=/tmp"); > > int i = 0; > > #ifdef STRACE_GDB > > av[i++] = "strace"; > > av[i++] = "-o"; > > av[i++] = "/tmp/strace.out"; > > #ifdef __CYGWIN__ > > av[i++] = "--mask=all+paranoid"; > > #endif > > #endif > > av[i++] = argv[1] ?: "gdb"; > > fprintf (stderr, "*** using %s\n", av[0]); > > av[i++] = "-i=mi"; > > av[i] = NULL; > > execvp (av[0], (char * const *) av); > > /* shouldn't get here */ > > exit (1); > > } > > /* parent */ > > const char *input[20]; > > > > int i = 0; > > input[i++] = "1-inferior-tty-set /dev/pty3\n"; > > input[i++] = "2-gdb-set height 0\n"; > > input[i++] = "3-gdb-set non-stop 1\n"; > > input[i++] = "4-file-list-exec-source-files\n"; > > input[i++] = "5-file-list-exec-source-file\n"; > > input[i++] = "6-gdb-show prompt\n"; > > input[i++] = "7-stack-info-frame\n"; > > input[i++] = "8-thread-info\n"; > > input[i++] = "9-break-list\n"; > > input[i++] = "q\n"; > > input[i] = NULL; > > > > for (int i = 0; input[i]; ++i) > > { > > write (master, input[i], strlen (input[i])); > > // sleep (1); > > } > > get_output (master); > > wait (NULL); > > } > > > > void > > get_output (int fd) > > { > > char buf[4096]; > > > > while (1) > > { > > int nread = read (fd, buf, sizeof (buf)); > > if (nread > 0) > > write (STDOUT_FILENO, buf, nread); > > else > > { > > printf ("No more output. nread %d\n", nread); > > break; > > } > > } > > } > > > > > > > -- > > Problem reports: http://cygwin.com/problems.html > > FAQ: http://cygwin.com/faq/ > > Documentation: http://cygwin.com/docs.html > > Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple > > > -- > Corinna Vinschen Please, send mails regarding Cygwin to > Cygwin Maintainer cygwin AT cygwin DOT com > Red Hat -- Takashi Yano --Multipart=_Mon__6_Jun_2016_19_12_31_+0900_Dvs56MeAlzKVfQ6l Content-Type: text/x-csrc; name="pty_readlen.c" Content-Disposition: attachment; filename="pty_readlen.c" Content-Transfer-Encoding: 7bit Content-length: 1382 #include #include #include #include #include #include int main() { int master, slave; struct termios tt; int val; char buf[1024]; int len; if (openpty(&master, &slave, NULL, NULL, NULL) < 0) { perror("openpty()"); exit(EXIT_FAILURE); } write(STDOUT_FILENO, "----------\n", 11); /* Write two messages */ write(master, "01234\n", 6); write(master, "56789\n", 6); /* Read (Canonical Mode) */ len = read(slave, buf, sizeof(buf)); if (len>0) write(STDOUT_FILENO, buf, len); /* Rrset Canonical Mode */ tcgetattr(slave, &tt); tt.c_lflag &= ~ICANON; tcsetattr(slave, TCSANOW, &tt); write(STDOUT_FILENO, "----------\n", 11); write(master, "ABCDE\n", 6); /* Read (Non-Canonical Mode) */ len = read(slave, buf, sizeof(buf)); if (len>0) write(STDOUT_FILENO, buf, len); write(STDOUT_FILENO, "----------\n", 11); /* Write two messages */ write(master, "FGHIJ\n", 6); write(master, "KLMNO\n", 6); /* Set Canonical Mode */ tcgetattr(slave, &tt); tt.c_lflag |= ICANON; tcsetattr(slave, TCSANOW, &tt); /* Flush buffer */ tcflush(slave, TCIFLUSH); val = 1; ioctl(slave, FIONBIO, &val); /* Read */ len = read(slave, buf, sizeof(buf)); if (len>0) write(STDOUT_FILENO, buf, len); write(STDOUT_FILENO, "----------\n", 11); close(slave); close(master); return EXIT_SUCCESS; } --Multipart=_Mon__6_Jun_2016_19_12_31_+0900_Dvs56MeAlzKVfQ6l Content-Type: text/plain; charset=us-ascii Content-length: 218 -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple --Multipart=_Mon__6_Jun_2016_19_12_31_+0900_Dvs56MeAlzKVfQ6l--