andrew@orca.UUCP (Andrew Klossner) (08/11/83)
Consider a program written for a 16-bit machine which uses printf("%X",(long)a) to print a long. This program might live into an era in which printf is redesigned so that the correct arguments become printf("%lx",(long)a), because "%X" has come to mean that upper case letters are to be used in the hexadecimal numeral. If this program had been constructed to use shared libraries, dynamically loaded at runtime, then it would seem to "break", despite the lack of changes to it. This is not a case of exploiting a library bug. What has happened is that the library has evolved and the program has remained static. -- Andrew Klossner (decvax!tektronix!tekecs!andrew) [UUCP] (andrew.tektronix@rand-relay) [ARPA]
tim@unc.UUCP (08/11/83)
All the user-visible problems that have recently been mentioned with respect to shared libraries, for instance programs breaking when the library changes, are equally true of any library when the program is relinked, which can reasonably be expected of any program in general use or of medium or large size. Given this, it is hard to take these objections seriously. A much more serious objection is that the addition of a new segment to each UNIX process, which seems to be the only clean way to do this, involves far-reaching and non-trivial changes in the kernel. I have yet to see anyone suggest solutions at this level; it's a little early to start talking about flag bits in page tables, when we don't even have an overall design for the thing. This sort of implementation-first thinking is just the thing that could cause the kernel to be munged beyond hope, or more likely keep the project from even getting off the ground. ___________ Tim Maroney duke!unc!tim (USENET) tim.unc@udel-relay (ARPA) The University of North Carolina at Chapel Hill
louie@cvl.UUCP (Louis A. Mamakos) (08/11/83)
Yes, it is true that if the shared libraries change, then existing programs will operate differently ('break'). From my experience, this has not been a problem. As a part of my work, I do systems hacking on a UNIVAC 1100 series systems which has shared libraries, and the thing that keeps everything working and (most) everyone happy is that the function of a specific shared library is \clearly/ and \completely/ defined. When working in a production environment, you don't just change the defintion of a commonly used library at a whim. The advantages of being able to fix a bug, and have ALL programs which use it get the new and updated copy greatly outweigh any of the other problems involved. Of course, this means that you MUST think about the functions that your library will perform before you rush ahead and implement it. Ready to repel flames, Louis Mamakos Internet: louie@cvl Usenet: ..rlgvax!cvl!louie
chris@umcp-cs.UUCP (08/11/83)
Everyone's got a point: shared libraries, if changed, will cause programs to break. So (says the pro-shared) don't change them; do them right the first time. Doing it right the first time is certainly commendable, but it's not always possible. One of the best things about Unix is that it isn't fixed. 4.2 doesn't look that much like V6 anymore. SysV seems to be even less like V6. As new hardware and software techniques are discovered, things will keep changing; flexibility is required. Something tells me that this is why any commercial system is never quite as good as the "hacks" like Unix. (And maybe Unix is going to fall by the wayside, once everyone starts using it and it's forced to become static.) Just a thought. - Chris PS How 'bout *optional* shared libraries? Seems to me this gets around most everyone's arguments. The old programs don't get them since you aren't recompiling them; the new ones do unless you say not to. With retrofit libraries, that keeps the workload down. (I know, I'm not the first one to propose this.) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci UUCP: {seismo,allegra,brl-bmd}!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris.umcp-cs@UDel-Relay
gwyn@brl-vld@sri-unix.UUCP (08/12/83)
From: Doug Gwyn (VLD/VMB) <gwyn@brl-vld> The first time, on your future shared-library UNIX system, that someone updates the shared library and introduces a bug that stops exec() from working, you may change your mind about it being hard to take such objections seriously.
dan@bbncd@sri-unix.UUCP (08/12/83)
From: Dan Franklin <dan@bbncd> What people seem to forget is that shared libraries would be easier to change in EVERY way. With respect to changes that might introduce bugs, shared libraries are actually superior to regular libraries, especially if they are done with the flexibility of Multics-style dynamic linking. When you made a change to the library, you would first make the change in a private version of the library that only your own process tree would use. Now every UNIX command (that you run) will get tested with the new library--a fairly complete test! There would be no possibility of releasing a version of the library in which exec did not work; on the contrary, library changes would be tested far more thoroughly than they are now. Once you decided to release the library, you would again find any remaining bugs much faster than with the current system, because EVERYTHING would be using it. And as soon as users found a sufficiently bad bug, they would just switch to the older version of the library, which you have of course retained in a well-known place. Meanwhile, you go and fix the bug, and now again EVERYTHING is using the fixed version. Someone else brought up the matter of incompatible changes, e.g. to the printf format characters. This is not an argument against shared libraries, but an argument against shared anything, including kernels. You can't make an incompatible change to the kernel without providing some provision for older programs; you would have to be just as careful with shared libraries. And you should already be taking that care with libraries, so that a program doesn't break merely because it's reloaded. (And thus make you think that it was the change you made before you reloaded that caused the problem!) Incompatible changes can almost always be avoided (printf CAN interpret both character sequences), but when they must happen, you can just keep the old version around for awhile. If a program were sufficiently ancient, you would have to have the older version of the library resuscitated from backup tapes, just as you would have to do anyway as soon as someone tried to recompile it. If you haven't made any incompatible changes to the kernel which require the new library, it will work just fine. If you have, well, the shared libraries don't matter; the program would still be broken anyway. In short, shared libraries (properly implemented) would make changing the library routines an easier, safer task than they are now. Dan Franklin
jbray@bbn-unix@sri-unix.UUCP (08/12/83)
From: James Bray <jbray@bbn-unix> Most certainly, the way to do it is to add multiple-segment referencing, and it is just as certainly non-trivial. Processes should be able to reference some reasonably large number of symbolically-named objects, and the kernel should take care of all details of finding them, loading them if necessary, and controlling the type (read-write-execute) of access. Or if one doesn't feel up to hacking dynamic linking into the kernel, the references could be interpreted and established at load time, --this also makes it optional, so that tasks which are paranoid about referencing potentially changeable run-time-libraries could instead use old-style libraries--, and the kernel would then have to simply verify at exec-time that every object which may be referenced by a process is in fact present, and then establish the correct binding in the process' address-space. The process would for example contain in its header information telling the kernel "I expect object <libc_version_ 12345> to be available, I intend to execute it, and I expect it to begin at 0400000 in my address space". It is not worth trying to do it on a machine that doesn't have reasonably sophisticated memory-management. This sort of scheme also gives one sharable memory, and one can probably also think of other nice things to do with it. Full-scale dynamic linking is the way to go, but this is the last stop along the road before you get there. Granted, the implementation would take some doing... By the way, I will ask again: has anyone out there actually seen the way system V actually does what it calls shared memory? I have yet to get my copy, and am dying to know what it looks like. Did they in fact completely redesign major chunks of the kernel, or is it some bizarre and ugly hack involving disk files or worse... --Jim Bray
gwyn@brl-vld@sri-unix.UUCP (08/12/83)
From: Doug Gwyn (VLD/VMB) <gwyn@brl-vld> UNIX System V shared memory sets up page table entries for the processes involved; what else did you expect? I wouldn't say they completely redesigned major chunks of the kernel, but exec, exit, etc. do have hooks into the shared-memory module. This shared memory is really shared memory. I believe it was added to UNIX by the Real-Time folks, who need this kind of thing. Sockets are not the universal answer to everybody's IPC needs.
drforsey@watcgl.UUCP (Dave Forsey) (08/13/83)
The arguments against the use of shared libraries seems to rest on the fact that the structural rather than the functional aspect of the library will change causing a large amount of managerial headaches. This problem goes away if the libraries are not affected by the structure of the data it is handed. Absurd? Perhaps. But reflect on the way that Smalltalk-80 works. Everything in the system is part of a shared library. Handing a floating point number instead of a SmallInteger to a method causes no problems because it still behaves as a "Number". While this can't handle everything it goes a lot further than any other system. This is, by the way, one of the reasons that "Object-Oriented Programming" is different than typical procedural languages and styles. This of course is opening up an old can of worms but...... Dave Forsey Computer Graphics Laboratory University of Waterloo. Waterloo Canada
zrm@mit-eddie.UUCP (Zigurd R. Mednieks) (08/13/83)
In Multics, optional, experimental, outdated, unsupported, and private shareable libraries (segments, really -- nothing distinguishes them from any other sort of program module) are implemented by using search paths for resolving references to outside objects. Cheers, Zig
zrm@mit-eddie.UUCP (Zigurd R. Mednieks) (08/13/83)
On machines with real two level memory management, like the 16000, you don't hve to worry about adding one more segment. In fact, the way to do it right is to add a segment per module of shared routines. So a program that uses both termcap and stdio would have at least three text segments. Simlarly, you could eliminate explicit data i/o by mapping data segments directly into a process's address spacve. But then, it's been done, read all about it in Organic's book "The Multics System." Cheers, Zig
ka@spanky.UUCP (08/15/83)
Adding shared memory to System V involved neither a complete redesign of major chunks of the kernel, nor did it involve a bizarre and ugly hack. UNIX has had the ability to share read only text segments between processes for a long time. Adding shared data segments required *adding* code to various pieces of the kernel to support the shared segments; in particular the code which sets up the page tables for a process now has to include entries to map the segements into the process's address space. But little if any code had to be *changed*. Kenneth Almquist
bob@ucla-locus@sri-unix.UUCP (08/16/83)
From: Bob English <bob@ucla-locus> How about providing a loader option that would "compile in" a specified shared library, thus insulating a program from all future shared library changes? If you kept the old versions of libraries around, you would be able to handle most (if not all) of the retrofit problems. Another possible solution is to keep old versions of library routines around forever, so that old programs find the routines they expect, and new programs get the new versions. This might apply only to genuine revisions, and not to bug fixes. --bob--
bob@ucla-locus@sri-unix.UUCP (08/16/83)
From: Bob English <bob@ucla-locus> I don't think that your argument is universally appropriate. On vax's, for instance, I think it would be moderately simple to add a second shared/read-only text segment. The only real implementation problems would be in modifying the loader to take advantage of it, and that certainly doesn't sound overwhelming. --bob--
silver@csu-cs.UUCP (08/19/83)
We use them on the HP9000 Series 500. The most common calls went into a special library that's loaded (once) by the OS during initialization. Almost ALL object files immediately "lost weight", a significant amount. Ergo, they load faster and eat less memory. We have had NONE of the problems discussed here (about breaking existing code, etc.), though the product is young yet. (We'll have to watch out for them, that's all.)