From owner-svn-src-head@freebsd.org Wed Aug 5 18:14:02 2015 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 488E19B3F34; Wed, 5 Aug 2015 18:14:02 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 20D3C1158; Wed, 5 Aug 2015 18:14:02 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.14.9/8.14.9) with ESMTP id t75IE1ZE055835; Wed, 5 Aug 2015 18:14:01 GMT (envelope-from jhb@FreeBSD.org) Received: (from jhb@localhost) by repo.freebsd.org (8.14.9/8.14.9/Submit) id t75IE1Xv055834; Wed, 5 Aug 2015 18:14:01 GMT (envelope-from jhb@FreeBSD.org) Message-Id: <201508051814.t75IE1Xv055834@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jhb set sender to jhb@FreeBSD.org using -f From: John Baldwin Date: Wed, 5 Aug 2015 18:14:01 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r286331 - head/usr.bin/truss X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 05 Aug 2015 18:14:02 -0000 Author: jhb Date: Wed Aug 5 18:14:01 2015 New Revision: 286331 URL: https://svnweb.freebsd.org/changeset/base/286331 Log: Rework get_string() to make it more robust when fetching strings of unknown length. In particular, instead of blinding fetching 1k blocks, do an initial fetch up to the end of the current page followed by page-sized fetches up to the maximum size. Previously if the 1k buffer crossed a page boundary and the second page was not valid, the entire operation would fail. Modified: head/usr.bin/truss/syscalls.c Modified: head/usr.bin/truss/syscalls.c ============================================================================== --- head/usr.bin/truss/syscalls.c Wed Aug 5 18:10:46 2015 (r286330) +++ head/usr.bin/truss/syscalls.c Wed Aug 5 18:14:01 2015 (r286331) @@ -539,44 +539,56 @@ get_struct(pid_t pid, void *offset, void } #define MAXSIZE 4096 -#define BLOCKSIZE 1024 + /* * get_string * Copy a string from the process. Note that it is * expected to be a C string, but if max is set, it will * only get that much. */ - static char * -get_string(pid_t pid, void *offset, int max) +get_string(pid_t pid, void *addr, int max) { struct ptrace_io_desc iorequest; - char *buf; - int diff, i, size, totalsize; + char *buf, *nbuf; + size_t offset, size, totalsize; - diff = 0; - totalsize = size = max ? (max + 1) : BLOCKSIZE; + offset = 0; + if (max) + size = max + 1; + else { + /* Read up to the end of the current page. */ + size = PAGE_SIZE - ((uintptr_t)addr % PAGE_SIZE); + if (size > MAXSIZE) + size = MAXSIZE; + } + totalsize = size; buf = malloc(totalsize); if (buf == NULL) return (NULL); for (;;) { - diff = totalsize - size; iorequest.piod_op = PIOD_READ_D; - iorequest.piod_offs = (char *)offset + diff; - iorequest.piod_addr = buf + diff; + iorequest.piod_offs = (char *)addr + offset; + iorequest.piod_addr = buf + offset; iorequest.piod_len = size; if (ptrace(PT_IO, pid, (caddr_t)&iorequest, 0) < 0) { free(buf); return (NULL); } - for (i = 0 ; i < size; i++) { - if (buf[diff + i] == '\0') + if (memchr(buf + offset, '\0', size) != NULL) + return (buf); + offset += size; + if (totalsize < MAXSIZE && max == 0) { + size = MAXSIZE - totalsize; + if (size > PAGE_SIZE) + size = PAGE_SIZE; + nbuf = realloc(buf, totalsize + size); + if (nbuf == NULL) { + buf[totalsize - 1] = '\0'; return (buf); - } - if (totalsize < MAXSIZE - BLOCKSIZE && max == 0) { - totalsize += BLOCKSIZE; - buf = realloc(buf, totalsize); - size = BLOCKSIZE; + } + buf = nbuf; + totalsize += size; } else { buf[totalsize - 1] = '\0'; return (buf);