From owner-freebsd-questions@FreeBSD.ORG Sun May 17 17:17:35 2015 Return-Path: Delivered-To: freebsd-questions@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 4D8A8AA3 for ; Sun, 17 May 2015 17:17:35 +0000 (UTC) Received: from mail.pchotshots.com (mail.pchotshots.com [12.172.123.237]) (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 045FE174F for ; Sun, 17 May 2015 17:17:34 +0000 (UTC) Received: (qmail 83686 invoked by uid 89); 17 May 2015 17:18:44 -0000 Received: from unknown (HELO ?12.172.123.228?) (bmettee@pchotshots.com@12.172.123.228) by mail.pchotshots.com with ESMTPA; 17 May 2015 17:18:44 -0000 Message-ID: <5558CCC8.9030704@pchotshots.com> Date: Sun, 17 May 2015 13:15:52 -0400 From: Brad Mettee User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 MIME-Version: 1.0 To: Ian Smith , andrew clarke CC: Trev Roydhouse , freebsd-questions@freebsd.org Subject: Re: Strange return codes from old but good C program References: <20150517204503.V69409@sola.nimnet.asn.au> <20150517124223.GA82704@ozzmosis.com> <20150517232103.V69409@sola.nimnet.asn.au> In-Reply-To: <20150517232103.V69409@sola.nimnet.asn.au> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-BeenThere: freebsd-questions@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: User questions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 17 May 2015 17:17:35 -0000 On 5/17/2015 12:43 PM, Ian Smith wrote: > On Sun, 17 May 2015 22:42:24 +1000, andrew clarke wrote: > > On Sun 2015-05-17 22:16:14 UTC+1000, Ian Smith (smithi@nimnet.asn.au) wrote: > > > > > Hi, > > > > > > I'm hoping someone can help me figure out the behaviour of a C program > > > executed repeatedly from a shell invoked by my freepascal program. > > > > > > If anyone might care to download > > > (258071 bytes), unzip it and run 'make', the supplied makefile - a copy > > > of unixl.mak - should provide ssystem compiled for long double precision > > > maths, just as I wanted, with the following output from gcc from FreeBSD > > > 4.5 to 9.3-RELEASE. (If clang has trouble on 10.X, please let me know) > > > > That makefile defaults to gcc but allows you to build it with clang > > (which spits out a bunch of warnings similar to gcc) using: > > > > make -f unixl.mak CC=clang > > Thanks, trying that on 9.3 .. ooo yes, lots of warnings until adding > #include to the #ifdef UNIX section, as you say. Remaining > are only warnings for a number of functions like: > ssystem.c:171:1: warning: type specifier missing, defaults to 'int' > [-Wimplicit-int] > main() > ^~~~ > ssystem.c:456:1: warning: type specifier missing, defaults to 'int' > [-Wimplicit-int] > func( t, yin, v ) > ^~~~ > ssystem.c:607:1: warning: control reaches end of non-void function > [-Wreturn-type] > } > ^ > > > > smithi@x200:~/de118i-2 % make > > > gcc -O2 -c ssystem.c > > > ssystem.c: In function 'resstate': > > > ssystem.c:150: warning: incompatible implicit declaration of built-in > > > function 'exit' > > > ssystem.c: In function 'main': > > > ssystem.c:180: warning: incompatible implicit declaration of built-in > > > function 'malloc' > > > > stdlib.h provides prototypes for exit() and malloc(). > > > > #include > > They're not declared or overloaded anywhere that I can see but did work? > > > > ssystem runs as well as ever, these warnings indicate no functional > > > issues, but they do highlight the author's poor (but unsurprising in > > > 1993, last updated 2004) choice of return codes both for real errors > > > (malloc, file I/O, and maths div by zero, bad args for trig functions > > > and such) which mostly exit(1) but some return 0 (!) - but when ending > > > successfully it returns _usually_ 22, but sometimes 11, or 10, both seen > > > so far, consistently when run with the same (different) parameters. > > > > The code looks like ancient K&R C, which was a lot more relaxed with > > syntax than modern ISO C compilers. Even by 1993, most C developers > > had moved on from K&R. > > If you check moshier.net, Steve's written heaps of stuff, advanced maths > libraries and lots more but I gather he's more a C user than developer. > > > > What's worse is I can't figure out where in ssystem.c any return code > > > might be set on completion of main(), which is just declared as: > > > > > > main() > > > { > > > > This is fine in K&R, but the ISO C prototype for main() without arguments is: > > > > int main(void); > > C is read-only for me, but that's what I've come to expect seeing. > > > > and ends with the last of its results and (accuracy) errors printf()s: > > > > > > ii += 6; > > > } > > > #if FPESHOW # floating point debug, here set to 0 > > > fperem(); > > > #endif > > > } /* end of main program */ > > > > > > No variables called rc or anysuch .. so what sets these odd retcodes? > > > > Normally you'd use a return statement, eg. > > > > #include /* prototype for printf() */ > > > > int main(void) > > { > > printf("Hello world.\n"); /* say hi */ > > > > return 0; /* return zero to the OS */ > > } > > > > I haven't checked the standard but it's plausible that the ISO C spec > > allows a random return code if none is given, especially if no > > prototype for main() is provided. > > Fair enough, but it doesn't seem properly random. Same parameters, same > result. Different parameters nearly always give the same result, but > not always. It could be an otherwise uninitialised value somewhere, but > why half of that sometimes? Or 10 (seen only on amd64 here)? > > Have you tried running 'ssystem test.ans' to compare test.ans > with test.ld? Ahah, that's just where I spotted those 10 and 11 values: > > smithi@x200:~/de118i-2 % ssystem < test.que > test.ans ; echo $? > 10 > > # above on amd64 (same result when built with clang), but on i386: > > smithi on t23% ssystem < test.que > test.ans ; echo $? > 11 > > Worse, NO other input parameters in *.que that I try, WON'T return 22 :) > > Instead of fixing the declaration and adding return 0, would exit(N) do? > > > There may be tools around to convert K&R C code to ANSI/ISO C syntax, > > rather than trying to do it by hand. The code may still need some > > tweaking, though, eg. return 0 from main(). > > This code has been used in some pretty high-powered long-term ephemeris > production - patches with 128-bit 'long long doubles' that purport to > track (eg) earth's eccentricity back ~1M years - so I'm loathe to mess > with it unless necessary. If I were going to touch it for porting I'd > need to clean up eg the errors like malloc and failure to find a needed > file, that now return 0 (!) also. > > If I could feel confident that success would never return 0 or 1 - the > case so far, over many runs recently - then I needn't worry. As is, I > loudly report any non-22 retcodes, so if it ever did return 0 or 1 then > at least the (perhaps many hours long) run would stop with that report, > so it's not bad in the worst case, but still I can't help wonder, why? > > > > I'd be grateful for any clue. So far I assume any return code > 1 is > > > success, so far so good - but it doesn't feel deterministic enough :) > > > > > > cheers, Ian (please cc me, I'm subscribed to the digest) > > > > Pretty sure I know you from FidoNet, years ago. Also Trev Roydhouse. > > AUST_C_HERE, or another echo, maybe? > > Indeed, I've wondered about that myself. Ah, those were the days .. :) > I'll reply privately re all that, but not tonight. > > Thanks for help and encouragement Andrew, > > cheers, Ian > _______________________________________________ > I have a pretty good idea of why certain values are returned most, but not all, of the time. Specific code paths within any given application will regularly leave some CPU registers loaded with specific values (the result of internal maths or pointer usage). What you're seeing, on a normal basis, is the result of these things occurring. The odd time that something else turns up is likely caused by an OS operation that altered the register that's being used for the return value. My suggestion for this specific case would be to find any exit points from the program that don't set a return value, and make sure they set it to something that makes sense. In main, make sure it exits with a 0 (return 0;). That way if you ever get a non-zero return value, you can be pretty sure that the app didn't terminate normally. (Polytropon says pretty much the same thing in his latest post) As for the function definitions causing problems, why not go ahead and modify them? You did say this code hasn't been touched in years, so it's not likely your work will get overwritten with a new release. Hope this helps. -- Brad Mettee