From owner-freebsd-hackers@FreeBSD.ORG Wed Apr 23 10:37:30 2008 Return-Path: Delivered-To: hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 32DBD1065674 for ; Wed, 23 Apr 2008 10:37:30 +0000 (UTC) (envelope-from keramida@ceid.upatras.gr) Received: from igloo.linux.gr (igloo.linux.gr [62.1.205.36]) by mx1.freebsd.org (Postfix) with ESMTP id 7DC1C8FC1B for ; Wed, 23 Apr 2008 10:37:29 +0000 (UTC) (envelope-from keramida@ceid.upatras.gr) Received: from kobe.laptop (adsl23-13.kln.forthnet.gr [77.49.150.13]) (authenticated bits=128) by igloo.linux.gr (8.14.2/8.14.2/Debian-3) with ESMTP id m3NAIqh1032008 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT); Wed, 23 Apr 2008 13:18:58 +0300 Received: from kobe.laptop (kobe.laptop [127.0.0.1]) by kobe.laptop (8.14.2/8.14.2) with ESMTP id m3NAIqtZ003652; Wed, 23 Apr 2008 13:18:52 +0300 (EEST) (envelope-from keramida@ceid.upatras.gr) Received: (from keramida@localhost) by kobe.laptop (8.14.2/8.14.2/Submit) id m3NAIjsT003651; Wed, 23 Apr 2008 13:18:45 +0300 (EEST) (envelope-from keramida@ceid.upatras.gr) From: Giorgos Keramidas To: Bernard van Gastel References: <7d6fde3d0804222240j6b42b77yd86d8accb5a959fa@mail.gmail.com> <20080423025048.6b51a580@bhuda.mired.org> <5F412E73-29FC-4876-A6F0-9BC269876192@bitpowder.com> Date: Wed, 23 Apr 2008 13:18:45 +0300 In-Reply-To: <5F412E73-29FC-4876-A6F0-9BC269876192@bitpowder.com> (Bernard van Gastel's message of "Wed, 23 Apr 2008 10:30:39 +0200") Message-ID: <87ej8w3md6.fsf@kobe.laptop> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.0.60 (berkeley-unix) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-MailScanner-ID: m3NAIqh1032008 X-Hellug-MailScanner: Found to be clean X-Hellug-MailScanner-SpamCheck: not spam, SpamAssassin (not cached, score=-3.908, required 5, autolearn=not spam, ALL_TRUSTED -1.80, AWL 0.49, BAYES_00 -2.60) X-Hellug-MailScanner-From: keramida@ceid.upatras.gr X-Spam-Status: No Cc: hackers@freebsd.org, Garrett Cooper , Mike Meyer Subject: Re: strdup(NULL) supposed to create SIGSEGV? X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 23 Apr 2008 10:37:30 -0000 On Wed, 23 Apr 2008 10:30:39 +0200, Bernard van Gastel wrote: > Op 23 apr 2008, om 08:50 heeft Mike Meyer het volgende geschreven: >> On Tue, 22 Apr 2008 22:40:21 -0700 >> "Garrett Cooper" wrote: >> >>> Hi all, >>> I made an oops in a program, which uncovered "feature" in >>> strdup(2) >>> that I wasn't aware of before. So I was wondering, is strdup(pointer >>> = NULL) >>> supposed to segfault should this just return NULL and set errno? >> >> Yes, it's supposed to segfault. Check out what, say, strcpy does if >> you ask it to copy a NULL pointer. And this is an improvement from the >> bad old days, when they would happily walk through memory starting at >> 0..... > > I don't like it this way. I would like: > > strdup(NULL) = NULL > strdup(string) = copy of string > > strcpy(NULL, NULL) = NULL > strcpy(s1, NULL) = ERROR > strcpy(NULL, s2) = NULL (with s2 unchanged) > strcpy(s1, s2) = normal > > But I am not sure of the implications. Maybe in some situation it is > bad... Anyone? Well-written programs already check for NULL before they call strdup(), so they won't be affected by changing strdup() to return NULL when a null pointer is passed to strdup(). What is more likely to happen is that _badly_ written programs will crash further down, at the place where the null pointer is actually used. So we'll be "hiding" the bug of strdup(NULL) and causing faults in other, possibly very far places in the program's execution path. That's not really a very good idea :( >> Besides, errno is used to signal errors from system calls. strdup >> isn't a system call, it's a library function (says so at the top of >> the man page). > > But strdup uses malloc, which is a system call (from the strdup manual: > If insufficient memory is available, NULL is returned and errno is set > to ENOMEM.) I have to disagree I'm afraid. The malloc() function is *not* a system call, although it may be mapped to low-level primitives like sbrk() or mmap(). In general, malloc() is a `special' library function that abstracts away the implementation specific details of obtaining memory from the kernel. There are implementations of malloc() out there that rely on certain system-specific features but are, otherwise, implemented *entirely* in userland code. Our own is one. The sources of FreeBSD's malloc() are in `/usr/src/lib/libc/stdlib/malloc.c' for anyone interested to read the source and see all the cool things Jason has done :)