Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site fortune.UUCP Path: utzoo!watmath!clyde!burl!ulysses!mhuxr!mhuxt!houxm!whuxl!whuxlm!akgua!gatech!seismo!lll-crg!lll-lcc!dual!ptsfa!qantel!ihnp4!fortune!olson From: olson@fortune.UUCP (Dave Olson) Newsgroups: net.unix,net.unix-wizards Subject: Re: "_doprnt" query Message-ID: <5807@fortune.UUCP> Date: Wed, 11-Dec-85 16:27:51 EST Article-I.D.: fortune.5807 Posted: Wed Dec 11 16:27:51 1985 Date-Received: Mon, 16-Dec-85 04:17:17 EST References: <280@ur-tut.UUCP> Reply-To: olson@fortune.UUCP (Dave Olson) Distribution: net Organization: Fortune Systems, Redwood City, CA. Lines: 49 Keywords: _doprnt _dontprnt _willprnt _wontprnt Xref: watmath net.unix:6635 net.unix-wizards:16113 As I'm sure you'll hear from many people, _doprnt is undocumented because it is not guaranteed to exist. On many V7 derived unix's it is used to implement printf, sprintf, and fprintf. NOTE: there are some more general comments at the end of this article, but the main part is specific to Fortune Systems products. If you are using the 1.7 LDT release from Fortune (try running 'what /usr/lib/libc.a' to get the version), the problem is probably due to the fact that doprnt was compiled with stack checking turned off. Most of the library routines were compiled this way for the sake of speed. Unfortunately, several routines (I believe they were just ecvt() and _doprnt(), but don't hold me to it :-) ) use quite a bit of stack for local variables (about 440 bytes for _doprnt()). As a result, when these routines are called, and a program is approaching the max stack allocated (initially 9K, and grows when a routine with stack checking on is called) calls printf(), you get a segmentation violation. There are two ways to fix this problem. The 'best' is to get the current Fortune LDT release (1.8.2). The second solution is to call a dummy routine that has a large local array. You'll have to experiment to see at what point you'll need to call it, or call it early in the program and make it a very large array. Stack is normally allocated in 8K increments by the kernel. The dummy routine doesn't have to do anything, just make sure it is in a file compiled WITHOUT the -G option. You can determine how much stack is allocated by running the command: pstat -u PID 1 | grep ssize where PID is the process ID of your program, and the '1' says to run pstat at one second intervals. MORE GENERAL QUESTIONS: I'm posting this here because it may be of general interest. More generally, how do other systems using the 68000 (NOT the 68010 or 68020, which allow you to restart an instruction on address errors) do stack checking, or do they do it at all? Fortune does it by calling a routine (csav, or csavl if floating point is used) to be sure sufficient stack is available at entry to a function. This call is inserted by the compiler, and assumes 'normal' conventions are followed; it may not work if you are using assembly language routines. It still has a problem when someone (generally a novice programmer) calls a routine with a LARGE strucure (NOT a pointer) as an argument. Dave Olson, Fortune Systems