From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from confino.investici.org (confino.investici.org [93.190.126.19]) by sourceware.org (Postfix) with ESMTPS id 7D4CA3854562 for ; Fri, 18 Nov 2022 19:54:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 7D4CA3854562 Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=autistici.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=autistici.org Received: from mx1.investici.org (unknown [127.0.0.1]) by confino.investici.org (Postfix) with ESMTP id 4NDSCp6jLxz117t for ; Fri, 18 Nov 2022 19:54:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=autistici.org; s=stigmate; t=1668801254; bh=w4QDZjgkPAjnlvi+02X0sosRYEq3pSq5kXg1TY0BWK8=; h=From:To:Subject:Date:From; b=WepGgisLAx+RUN6gNBiFUkAyouznk2ZPwgB8IN5dC1WvO7eHCSveL2IOWfYDel9tT vP4dIhbLbIxngzP9gEk05s5hQuaWBgWRAcHcKBTiU8QK2s1SOXxf94NGyJDkYQ5uRc eglTKju7ZpiCoioVc5Ddth7wXvHY9gflp1woQ1pk= Received: from [93.190.126.19] (mx1.investici.org [93.190.126.19]) (Authenticated sender: andrea.monaco@autistici.org) by localhost (Postfix) with ESMTPSA id 4NDSCp5pqFz117m for ; Fri, 18 Nov 2022 19:54:14 +0000 (UTC) From: Andrea Monaco To: gdb@sourceware.org Subject: Program with pseudo-tty behaving differently in single-step Date: Fri, 18 Nov 2022 20:54:13 +0100 Message-ID: <87a64om42i.fsf@autistici.org> MIME-Version: 1.0 Content-Type: text/plain X-Spam-Status: No, score=-3.1 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_PASS,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: I have a program that behaves very differently when single-stepping and when running freely in gdb. The first part of the program opens a pseudo-terminal pair in the usual way. This pair includes a master (that sort of simulates the user: you can read from master and write to master like a human would do) and a slave (that the child process uses as a terminal for stdin and stdout, receiving what you send to master and sending back to master). The child process runs bc (a calculator). The parent sends the line "1+1\n" and reads back the subsequent line. #define _GNU_SOURCE #include #include #include #include #include #include char buffer [1024]; int master, slave; ssize_t readl (int fd, char *buf) { ssize_t i = 0; do { read (fd, buf+i, 1); } while (buf [i++] != '\n'); return i; } int main (int argc, char *argv []) { int i; char *name; pid_t child; master = getpt (); if (master < 0) { perror ("getpt() failed"); return 1; } if (grantpt (master) < 0 || unlockpt (master) < 0) { perror ("grantpt() or unlockpt() failed"); return 1; } name = ptsname (master); if (!name) return 1; slave = open (name, O_RDWR); if (slave < 0) { perror ("could not open slave"); return 1; } /* until now, we opened a pseudo-tty pair in the standard way */ child = fork (); if (child < 0) { perror ("fork failed"); return 1; } if (!child) { /* in the child, we close stdin and stdout and substitute them both with the slave pseudo-terminal for input and output */ close (1); close (0); if (dup (slave) == -1 || dup (slave) == -1) { perror ("dup failed"); return 1; } execlp ("bc", "bc", NULL); perror ("could not exec bc"); } /* in the parent, we skip the startup message of bc */ for (i = 0; i < 4; i++) { readl (master, buffer); } write (master, "1+1\n", strlen ("1+1\n")); readl (master, buffer); /* we skip the echo line of 1+1 */ read (master, buffer, 3); /* now we read the result line */ buffer [3] = '\0'; printf ("%s", buffer); return 0; } In gdb, when I do a run I get "1+1" as output. When I single-step, I get 2 from the last printf instead, which is the desired output. Can anyone replicate this? Is there a known explanation? Andrea Monaco