jer@peora.UUCP (J. Eric Roskos) (09/09/85)
> The MMU is the answer.
I disagree with this. Unless you design your microprocessor architecture
from the beginning to require an MMU.
I was thinking about this question this weekend while trying to debug two
very frustrating errors in a C program I was writing on my IBM PC (a UUCP-
interfacing mailer). There were two things badly needed.
1) The ability to trap when JUST ONE particular address was generated as a
data reference. There was this pointer, somewhere in this 80K program,
which was overwriting part of an error message, so that a garbage character
showed up whenever the error message came out. Apparently it was just
using the byte in the error message as the location for a variable, instead
of the byte it was supposed to use, because the program ran perfectly -- it
just had this strange character in the middle of the error message. Now,
if I could just have had the machine trap when that character was written
to, I could have found out immediately where the error was. As it was, I
still don't know where the error is... and probably will have to spend
several hours hunting for it. This isn't such a major addition to the
microprocessor; and the problem it solves is not that uncommon, and is one
of the most difficult to debug.
2) Checking for stack integrity. In this same program, a return address on
the stack was getting overwritten, causing the program to branch off into
the data when some subroutine returned. Finding this required putting in
some "I'm returning now...now I'm back" messages in a number of routines to
discover which one actually was doing it. This one is a little harder to
implement, but certainly would help.*
The reason I say I disagree with the "in the MMU" approach is that
currently most people treat MMUs as optional devices. This means that any
application in which you use a microprocessor but don't use an MMU won't
have access to such facilities; and I think that for microprocessors, the
non-MMU applications probably far exceed the ones that use MMUs (I'm
referring here to the use of microprocessors in controllers, etc.).
----------
*I'm sure at least someone is wondering what the cause of this error was...
Well, it turns out that with this particular C compiler, if you give
certain invalid values to the "mode" parameter of the creat() system call,
it overwrites the stack... don't ask me why...
--
Shyy-Anzr: J. Eric Roskos
UUCP: ..!{decvax,ucbvax,ihnp4}!vax135!petsd!peora!jer
US Mail: MS 795; Perkin-Elmer SDC;
2486 Sand Lake Road, Orlando, FL 32809-7642
res@ihlpl.UUCP (Rich Strebendt @ AT&T Information Systems - Indian Hill West; formerly) (09/11/85)
> > The MMU is the answer. > > I disagree with this. Unless you design your microprocessor architecture > from the beginning to require an MMU. > > I was thinking about this question this weekend while trying to debug two > very frustrating errors in a C program I was writing on my IBM PC (a UUCP- > interfacing mailer). There were two things badly needed. > > 1) The ability to trap when JUST ONE particular address was generated as a > data reference. I agree with the usefulness of this ability -- though I would not limit it to JUST ONE of anything. I prefer the trap setting ability I had years ago working with IBM TSS. There were three types of traps that I found very useful in debugging a large program: a) Trap on a data store into any location in a specified range. Trapping on stores to locations in the range 0-256 often caught stores through null or nearly null pointers. b) Trap on an instruction fetch from any location in a range of addresses. Very handy for catching a wild branch. c) Trap on any change to a specified register. Handy to monitor returns from subroutines (R13 changed, I think -- it has been a while!) to find out whither they were returning -- or when the return address was being clobbered. > The reason I say I disagree with the "in the MMU" approach is that > currently most people treat MMUs as optional devices. This means that any > application in which you use a microprocessor but don't use an MMU won't > have access to such facilities; and I think that for microprocessors, the > non-MMU applications probably far exceed the ones that use MMUs (I'm > referring here to the use of microprocessors in controllers, etc.). I strongly agree. I am developing firmware (board resident software) for a controller. All addressing is done on-board without an MMU. The stack-overflow exception has helped catch and make known a couple of bugs. The trap facilities above would have made finding a couple of others a good bit easier. Rich Strebendt ...!ihnp4!iwsl6!res
dougp@ISM780.UUCP (09/11/85)
It's these kinds of problems which have led me to conclude that the *only* reasonable debugging tool for micros is an in-circuit emulator. Once you've had the pleasure of being able to trap on exactly these conditions (specific addresses being used to reference data, a particular data byte being written somewhere, etc) you get really spoiled. For an IBM PC, you might try the ATRON PC PROBE. Atron is in the San Jose, CA area, somewhere. They have a real nice board which does reasonable emulation and costs less than $2K. The only catch is that you have to start it from MS/PC-DOS (you can then re-invoke the bootstrap in the ROM, however...). Doug Pintar at Interactive Systems Corp.
jer@peora.UUCP (J. Eric Roskos) (09/16/85)
> For an IBM PC, you might try the ATRON PC PROBE. Atron is in the San Jose, > CA area, somewhere. They have a real nice board which does reasonable > emulation and costs less than $2K. Yes, I've used ICEs before (I like the "logic analyzer" type that clip on to the microprocessor, rather than an emulator, though, since those emulators sometimes have strange timing properties). But my point was, you shouldn't have to spend $2000... I mean, I certainly am not going to for my personal IBM PC when I can just spend a few hours (worth much less than $2000) and find it by hand. If it's built into the microprocessor, though, then that's a big improvement... -- Shyy-Anzr: J. Eric Roskos UUCP: Ofc: ..!{decvax,ucbvax,ihnp4}!vax135!petsd!peora!jer Home: ..!{decvax,ucbvax,ihnp4}!vax135!petsd!peora!jerpc!jer US Mail: MS 795; Perkin-Elmer SDC; 2486 Sand Lake Road, Orlando, FL 32809-7642
mac@uvacs.UUCP (Alex Colvin) (09/16/85)
> > 1) The ability to trap when JUST ONE particular address was generated as a > > data reference. The Honeywell (formerly GE) mainframes also have this ability, much like the IBM machines cited above (335@ihlpl). It does come in handy for debugging the kernel, but since the address is absolute, it's not much use to time-sharing users. I'm still looking for a machine that will trap references to uninitialized data.
res@ihlpl.UUCP (Rich Strebendt @ AT&T Information Systems - Indian Hill West; formerly) (09/19/85)
> > > 1) The ability to trap when JUST ONE particular address was generated as a > > > data reference. > > The Honeywell (formerly GE) mainframes also have this ability, much like > the IBM machines cited above (335@ihlpl). It does come in handy for > debugging the kernel, but since the address is absolute, it's not much use > to time-sharing users. Just a quick clarification on the IBM TSS/370 traps: those traps that worked on addresses worked on virtual addresses. Thus, they were of great value to a time-sharing program developer. Rich Strebendt ...!ihnp4!iwsl6!res
cdshaw@watmum.UUCP (Chris Shaw) (09/19/85)
In article <1599@peora.UUCP> jer@peora.UUCP (J. Eric Roskos) writes: >1) The ability to trap when JUST ONE particular address was generated as a >data reference. I've used a marvelous tool for this problem.. It's called a logic analyzer. Unfortunately, they are expensive, and on systems which do a lot of address translation, figuring out what address you REALLY want might be a problem. For reasonably ordinary (micro) systems, however they're great. I remember testing some 1802 code one time, using the most primitive debugging method in existence: "It doesn't work, now figure out why !". A logic analyzer killed my bug in no time. Chris Shaw watmath!watmum!cdshaw or cdshaw@watmath University of Waterloo A doze by any other name would be a sleep. - Shakesfeare
jer@peora.UUCP (J. Eric Roskos) (09/19/85)
> I'm still looking for a machine that will trap references to uninitialized > data. This is a hard problem. My dissertation advisor (R. I. Winner) did a good bit of research on this problem; see, for example, Winner, R. I., "Unassigned Objects," ACM TOPLAS, October, 1984. The problem is that either you have to have a unique bit pattern representing unassigned data (which means there's one value that has a special meaning), or you have to have a tag bit denoting "unassigned". Various interesting models of memory are possible if you generalize the unassigned object. -- Shyy-Anzr: J. Eric Roskos UUCP: Ofc: ..!{decvax,ucbvax,ihnp4}!vax135!petsd!peora!jer Home: ..!{decvax,ucbvax,ihnp4}!vax135!petsd!peora!jerpc!jer US Mail: MS 795; Perkin-Elmer SDC; 2486 Sand Lake Road, Orlando, FL 32809-7642
tom@hcrvx1.UUCP (Tom Kelly) (09/19/85)
In article <2384@uvacs.UUCP> mac@uvacs.UUCP (Alex Colvin) writes: > >I'm still looking for a machine that will trap references to uninitialized >data. The Burroughs B7700 and its relatives (B6700, etc.) can do this. All memory locations have a three bit "tag" that indicates what kind of data is stored in the memory location (code, operand, pointer, ...). One of the tags (6) is "reserved for software control". The hardware considers it an unitialized operand. Reference to it for the purpose of computation causes a fault. (There is a special code sequence that can be used to get at the contents, but the compilers don't use that code when using it as a normal operand). A normal store operation would overwrite the tag 6. The Pascal compiler I worked on initialized all scalar local variables to have tag 6. If you used them without initializing them, you'd get an abort with the message "Invalid Operand". The Tasmania Pascal compiler for the B6700 also put a tag 6 into the control variable of a for loop at loop exit, since the value is supposed to be indeterminate. I found this to be very helpful in debugging programs. Tom Kelly (416) 922-1937 {utzoo, ihnp4, decvax}!hcr!hcrvx1!tom
jans@orca.UUCP (Jan Steinman) (09/19/85)
In article <2384@uvacs.UUCP> mac@uvacs.UUCP (Alex Colvin) writes: >>> 1) The ability to trap when JUST ONE particular address was generated as a >>> data reference. > >The Honeywell... mainframes also have this ability, ... but since the >address is absolute, it's not much use to time-sharing users. > >I'm still looking for a machine that will trap references to uninitialized >data. (I still stand by my statement that such things belong in the (either on or off chip) MMU.) The NS32000 MMU has two registers for reference breakpointing. These can be set up for either data or program, initialized or not, as either physical or virtual addresses. I used them heavily for debugging a reference counting garbage collector. (Alright! Who set that reference count to -1!) Unfortunately, the reference breakpoints are broken on the latest mask. 8 -- :::::: Artificial Intelligence Machines --- Smalltalk Project :::::: :::::: Jan Steinman Box 1000, MS 61-405 (w)503/685-2956 :::::: :::::: tektronix!tekecs!jans Wilsonville, OR 97070 (h)503/657-7703 ::::::
thoth@tellab2.UUCP (Marcus Hall) (09/21/85)
In article <2384@uvacs.UUCP> mac@uvacs.UUCP (Alex Colvin) writes: > >I'm still looking for a machine that will trap references to uninitialized >data. Hasn't this been implemented in some system by faking a parity error on all uninitialized data. After trapping on the parity error, if what's there is the same as the bit "special" pattern, it's a pretty good guess that it's uninitialized (as distinguished from a real live parity error). I'm fairly sure that I have seen this somewhere, but I'm not quite sure where it was. It requires being able to write a word with bad parity (not too hard, I guess) and is essentially very kludgy, but it doesn't cost an extra bit just to tell if the area is uninitialized. marcus hall ..!ihnp4!tellab1!tellab2!thoth
joe@petsd.UUCP (Joe Orost) (09/25/85)
In article <3563@tellab2.UUCP> thoth@tellab2.UUCP (Marcus Hall) writes: >In article <2384@uvacs.UUCP> mac@uvacs.UUCP (Alex Colvin) writes: >>I'm still looking for a machine that will trap references to uninitialized >>data. > >Hasn't this been implemented in some system by faking a parity error on all >uninitialized data. After trapping on the parity error, if what's there is >the same as the bit "special" pattern, it's a pretty good guess that it's >uninitialized (as distinguished from a real live parity error). > >I'm fairly sure that I have seen this somewhere, but I'm not quite sure where >it was. It requires being able to write a word with bad parity (not too >hard, I guess) and is essentially very kludgy, but it doesn't cost an extra >bit just to tell if the area is uninitialized. What happens on a machine with virtual memory, or even swapping? How do you swap out/in a parity error? Do you have to lock in all pages that have parity errors anywhere jammed in them? What about an uninitialized array of bytes. Say you want to set the first byte = 0. So, you execute a store byte instruction. Now, most processors that I know of do a store byte by doing a load fullword, inserting the byte, and doing a store fullword. BANGO! a parity error! No wonder Ada doesn't require unitialized variable checking! regards, joe -- ........ ......... Full-Name: Joseph M. Orost . . . UUCP: ihnp4!vax135!petsd!joe . ...... ... ........ ARPA: vax135!petsd!joe@BERKELEY . . Phone: (201) 758-7284 . ......... Location: 40 19'49" N / 74 04'37" W US Mail: MS 313; Perkin-Elmer; 106 Apple St Tinton Falls, NJ 07724
jer@peora.UUCP (J. Eric Roskos) (09/27/85)
Joe Orost writes: > What about an uninitialized array of bytes. Say you want to set the first > byte = 0. So, you execute a store byte instruction. Now, most processors > that I know of do a store byte by doing a load fullword, inserting the byte, > and doing a store fullword. BANGO!* a parity error! > > No wonder Ada doesn't require unitialized variable checking! There's another problem related to arrays, also. Suppose you have an array, some of whose elements are uninitialized. Then should the whole array be treated as uninitialized, or not? Either way you can find cases where you need it to be the other way. The above example relates to a more general problem of implementing tagged architectures, viz., do you put tags on bytes, or words, or what? If you put the tags on bytes, then when you have a data type that is, say, a word, you have that problem with how to handle arrays with some uninitialized and some initialized elements, again... (if you allow someone to access the word as bytes sometimes too, at least). -- Shyy-Anzr: J. Eric Roskos UUCP: Ofc: ..!{decvax,ucbvax,ihnp4}!vax135!petsd!peora!jer Home: ..!{decvax,ucbvax,ihnp4}!vax135!petsd!peora!jerpc!jer US Mail: MS 795; Perkin-Elmer SDC; 2486 Sand Lake Road, Orlando, FL 32809-7642 *"But, I want one what goes `WANGO'!" -- From a 1950s Pogo comic strip
atbowler@watmath.UUCP (Alan T. Bowler [SDG]) (10/11/85)
In article <2384@uvacs.UUCP> mac@uvacs.UUCP (Alex Colvin) writes: >> > 1) The ability to trap when JUST ONE particular address was generated as a >> > data reference. > >The Honeywell (formerly GE) mainframes also have this ability, much like >the IBM machines cited above (335@ihlpl). It does come in handy for >debugging the kernel, but since the address is absolute, it's not much use >to time-sharing users. > >I'm still looking for a machine that will trap references to uninitialized >data. The timesharing user has the debugger which allows you to stop execution on a reference to or an attempt to change any address or range of addresses