From owner-freebsd-hackers Wed Dec 20 7:41:16 2000 From owner-freebsd-hackers@FreeBSD.ORG Wed Dec 20 07:41:14 2000 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from herd.plethora.net (herd.plethora.net [205.166.146.1]) by hub.freebsd.org (Postfix) with ESMTP id 549DD37B400 for ; Wed, 20 Dec 2000 07:41:13 -0800 (PST) Received: from guild.plethora.net (root@guild.plethora.net [205.166.146.8]) by herd.plethora.net (8.9.0/8.9.0) with ESMTP id JAA04528 for ; Wed, 20 Dec 2000 09:41:12 -0600 (CST) Received: from guild.plethora.net (seebs@localhost.plethora.net [127.0.0.1]) by guild.plethora.net (8.9.3/8.9.0) with ESMTP id JAA15236 for ; Wed, 20 Dec 2000 09:41:11 -0600 (CST) Message-Id: <200012201541.JAA15236@guild.plethora.net> From: seebs@plethora.net (Peter Seebach) Reply-To: seebs@plethora.net (Peter Seebach) To: freebsd-hackers@freebsd.org Subject: Re: Why not another style thread? (was Re: cvs commit: src/lib/libc/gen .. In-reply-to: Your message of "20 Dec 2000 15:42:19 +0100." <5ld7enduic.fsf@assaris.sics.se> Date: Wed, 20 Dec 2000 09:41:11 -0600 Sender: seebs@plethora.net Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG In message <5ld7enduic.fsf@assaris.sics.se>, Assar Westerlund writes: >Aled Morris writes: >> On Mon, 18 Dec 2000, Matt Dillon wrote: >> > void * >> > safe_malloc(int bytes) >> > { >> > void *ptr; >> > if ((ptr = malloc(bytes)) == NULL) >> > *(int *)0 = 1; /* force seg fault */ >> Shouldn't you use "kill(0, SIGSEGV)" ? >Why not err(3) or abort(3) ? Okay, from a style standpoint, the basic problem is that this function is a mistake. Programs may have temp files open, they may have stty settings to reset, there are tons of things you may need to do *BEFORE EXITING*. With that in mind, it becomes clear that you *can't* just abort-on-failure. Yes, it's a pain having every malloc() check for resources, but you *have to do it*, or you will litter the disk with forgotten files, break the user's terminal, and otherwise act like Microsoft Linux. You just have to handle each failure as it comes. Some require you to punt and go back and clean up all your work and exit gracefully. Others may have options open, where you can free something up, or ask for a little less. Of course, this is all made harder by the current fad of overcommitting; malloc can return a perfectly "good" pointer which you can't actually dereference later. I would like to point out that the original code is abjectly silly; after all, the pointer is likely to get referenced soon enough. At a bare minimum, the Correct Thing would be #define safe_malloc(x) safe_malloc_internal((x), __FILE__, __LINE__) void *safe_malloc(size_t bytes, char *file, int line) { void *p = malloc(bytes); if (p == NULL) { fprintf(stderr, "can't allocate %lu bites at file %s, line %d.", (unsigned long) x, __FILE__, __LINE__); exit(EXIT_FAILURE); } } But that still presupposes it ever makes sense to just puke and die on a failed malloc. It might be reasonable to omit the exit(), and then, even if you segfault immediately after the malloc, you'll have logged what killed you. (In an ideal world, you'd have the program name in here.) (In an even more ideal world, you'd have C99, and you'd use %ju, and cast x to uintmax_t, because we don't know how large size_t will be in the future.) But really, the best implementation of safe_malloc is void *safe_malloc(char bytes) /* might as well, who cares? */ { #error "Malloc is about as safe as free climbing on large mountains." } -s To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message