The question is, if you restrict yourself in that way, do you give up a major feature of the language? The answer is Yes -- you lose polymorphism, in effect. In order to use objects polymorphically, you must pass pointers to them. The pointers can be upcast/downcast. If you don't pass a pointer, then your object is stripped.
This is a good question; how many features should be actually used? C++ has many and it is possible to choose only certain ones. Maybe polymorphism would have to be avoided.
Admittedly, it is possible to pass around pointers to stack-based objects. But in my experience, you don't end up with safe code. What you want is reference-counted objects. Such objects must be allocated on a heap.
Hmmm, I haven't had problems with stack pointers, but I hardly use them either. Ref-counted (or tracked) objects ARE easier because you can store them. I don't use much heap allocation, but I also don't use many virtual functions or much inheritance.
There IS an offical distrobution. There are specific people that decide what code goes into this package. They do have standards. I can see it as a practical problem for the Linux kernel if all the current devs are used to C only, but that really isn't a good reason to not use C++ in general for kernels. The community has changed in the past; this wouldn't happen overnight.
C is plenty possible to abuse, espescially in kernel code. I've heard about all kinds of kernel patches that were not put in the main distro because they were messy/unstable without serious clean-up.
Suppose this code is written in C++, can you tell me what it does?
Suppose this code is written C, can you tell me what it does?
f();
In fact that is only possible if you have read all the definitions of f() and any functions it calls. It needs documentation.
Anyways: Objects x and y of type SomeType are created with the default constructor. You call the assignment operator on y with an argument of 3: you should have initialized y with 3 when you declared it. The addition operator is called on y with an argument of 5. The return value of this function will likely become a temporary, assuming a normal use of this operator. The assignment opeator is called on x with a parameter from the return value of the above function. You should have initialized x to this value instead of using assignment (assuming a sane definiton of the assignment operator).
In fact that is only possible if you have read
all the definitions of SomeType and any classes that it may inherit from.
This is only true if you have no standards on the code in your classes. Done correctly, it does not matter how the functions work as long as they are correct and their dependencies are known (when needed).
Operator overloading forces the reader to look at all definitions inherited when determining what the "=" and "+" operators do.
While it is possible to make the "=" and "+" operators do stupid things like output "HI" to the console, that is delibrate obfucation of code; abuse of the language. Operator overloading should only be used when it provides simple and intuitive convenience to code. If SomeType.operator =() doesn't do assignment then it shouldn't be overloaded. If SomeType doesn't make sense to use + with then that souldn't be overloaded either. You could easily make it a code policy that operators cannot do anything more than trivial processing: that they cannot allocate/free memory, access anything outside the class or parameters, or raise exceptions. Any deviation from this policy would represent invalid code. That way, you wouldn't need to know how the the operators work, just that they do what is obvious without complications. This is the basis of abstraction. You face the same need for standards for writing ANY function. Operators, like many things can be bad if used incorrectly. So can pointers.
A good use of operator overloading is the creation of new types. Take a 128 bit integer: most compilers do not have a primitive type for it. In C, you would have to make specialized handling every time you wanted to use the number; a typedef would be out of the question. You would have to maintain a seperate code base for this; you would have to make sure every change is replicated across both sets of code. With operator overloading in C++, you simply overload the operators to do the same thing they would do with a primitive type. The new type can be used with exactly the same code as an int64 and the meaning will be just as obvious.
Add exception handlng to the mix and it will be very hard to make the kinds of guarantees about layout, timing, flow control and order of evaluation that need to be enforced in a working kernel.
If you read my earlier post, you would know that I never advocated the use of exceptions; in fact, I try to avoid them.
C++ is every bit as detirministic as C is. It is one of the language's biggest strengths. Order of evaulation is exactly the same, BTW.
Temporary objects. Compilers create temporary objects, especiall arounjd function calls/returns. These call the constructor, which may call malloc. The number of situations temporary objects can be made is actually failry high and very complex. If the language is creating objects you don't explicitly ask for and calling malloc off that, I count that as the language using memory. Its the fault of the language for creating the object.
Don't use classes that call malloc on copy. This would be the library in which the class belong's fault. Either that or always pass by reference or pointer; no copy required. Use const if you don't want the value changed. This can be a rule for the project.
Like I said- function pointers. Like this:
You're right. I wasn't thinking about that. Still, you can't inline across function pointers. That could lead to bigger code if the function body uses less instructions than a function call.
struct outer{ int handle; }
struct inner{ int x,y; }
int some_privlidged_func(outer *o){ inner *in= (inner*)o->handle;//now just reference inner->x and inner->y }
Ick, this assumes that sizeof(int) == sizeof(void *); that is a bad assumption for portable code. Also, you have a one member structure. A better idea would be an empty structure for outer; cast a pointer to outer to get inner. I guess this would work pretty good, although you would have to maintain functions to access any data inside of inner whereas you could get to it directly with public. That was my point, that public/private is more convenient than handles. It lets you concentrate more on important things rather than wasting time writing glue functions, as you must to access any properties of a handle.
It gives them additional ways to break the rules. The more rules, the more people will want to break them, or just waste your time disagreeing with them. Its a social problem, not a technical one. And with larger teams, its a larger problem (with small teams the team probably made the rules themselves and hashed out differnces then). On a small 3-5 person project restricting features works. On large ones it just becomes a hassle. On very large ones with more than 1 gatekeeper to the code, it breaks down entirely (all you need is 1 lazy/disagreeing member with check in privlidges).
Kernel code already has a million ways to do bad things. Having a different language won't make it much worse. Done properly, C++ can help you write better code that is MORE resilient to idiocy, not less, using namespaces, new types by overloading, smart/safe pointers, templates, member protection...
Read Meyer's "Effective C++" and "More Effective C++". There's a lot of hidden object creation that goes on. These take memory. If they malloc memory in constructors, they use LOTS of memory.
Care to cite specific examples where C++ the language itself causes hidden memory allocation? I'm not talking about libraries, but the language. You can use libraries that don't do that. Libraries that do bad things behind the scenes are as big a risk in C as they are in C++.
Member functions are nice for associating a function with an object.
We have that. Function pointers. Kernel uses them all over.
I'm saying to use member functions for the orginazation they provide. You could get somthing similar with a good naming convention. This OTOH is supported by the language.
Static data variables do the same thing for single instance. For multi instance hold a pointer to a block of data, hold it in an integer, and call it a handle. Don't let the other guy see the implementation of the block.
Handles are more difficult to implement than simple pointers. You can't go from a pointer system with all public vars to a handle system very easily, whereas you can add private members to an existing structure easily.
The problem goes back to the top- you're hoping that you can get hundreds of developers with no central control to follow a bunch of rules. They won't. They don't on propriatary projects when they're being paid to do so. On an open source project, it'll be worse. Its easier just not to use C++ than to say "Use C++ but not features x,y, and z".
The Linux kernel has an official distrobution and it has central control. I hear about kernel patches all the time that don't get accepted into the main codebase.
Having developers that don't follow rules and write sloppy code is a much bigger problem than a change of language can fix. Bad developers will write bad code no matter the language. There are plenty of rules you can break to make bad code in C too. There are plenty of rules in kernel code that bad developers will break, too. I can't imagine that C++ would make that big a difference; there will still be programmers that disregard the rules.
This may not be the original intent of the article, but C++ does have features that C doesn't that won't cause any of these problems. It is better to attack specific features that are likely to be problematic instead of the entire language.
Don't like exceptions? Don't use them. C++ doesn't require you to. Personally, I don't use them unless I have to interface with other code that does. I usually compile with exception support off.
Is allocating memory in a constructor likely to cause problems? Make it a standard code practice for your project to never cause non-explicit memory allocation. Destructors can be forced to run at a specific time with delete or by using forced scopes (use {} around the lifetime of the local var). Copying objects in a standard way is easy to do, espescially if you always pass classes (structs) as references or by pointer.
Memory is tight, and mallocing will kill you performance wise if you need to grab a new free page. It may not even be possible to do if interrupts are locked. Its a hassle.
Are you saying that C++ always uses more memory than C? That's silly. If you can't call memory allocation functions right now, then allocate things on the stack. Make sure that the objects you create and the functions you call don't alloc either. You would have to make sure the functions were safe in C too.
In fact, a lot of embedded project don't even allow dynamic memory. I design printer firmware. We are not allowed to call malloc. All memory is tightly controlled by thesystem and is strictly deterministic to ensure we can always do a job. A large amount of object creation doesn't make sense in an embedded/kernel environment.
Ok, so don't use the heap. There is no reason that C++ needs to use the heap; everything can be allocated on the stack. Just like C.
Third- why not? There's places where its the best tool fro the job. Assembly gets a bad rap, really its a nice simple language. The real question is- what does C++ give you that C doesn't? Objects- C has them. Inheretance? Very rarely does it really benefit you, its usually used because "we're OO, we're supposed to use it". Templates? Ok, those can be useful for things like linked lists, although the STL goes way over the top with it. Exceptions? See above. The gains of C++ are minimal, the pain of it is large.
Assembly isn't too nice if you care about portability. It also depends on the architecture about how nice and simple it is. Segmented memory in assembly can be a nightmare.
Don't use the STL implementation of linked lists if you don't like it. Done properly, you could use templates for even more than that, like different index sizes for a filesystem; a 32 bit version for small volumes, a 64 for large volumes and a 128 for extremely large volumes. Since there is no primitive 128 bit type, C++ lets you override operators to create a new type that acts exactly like a primitive. This word size would be a template parameter of the filesystem class; a static version created for 32, 48, 64 and 128 bit or whatever. One code set, no redundancy. Remember the Sun story about a 128 bit filesystem? It could be as easy as recompilation!
How about namespaces? These would be very useful in the kernel, IMHO. Member functions are nice for associating a function with an object. Private data members allow you to put data in a structure that outside code doesn't need to know about so you can change it later without breaking compatibility. Documentation can do it too, but this can enforce it. I bet there could be some good uses for smart pointers.
The fact that a language has a feature does not obligate you to use it. You can use code standards in your project that set sane regulations for the code in the project. You need standards for any a sizable project in ANY language, including C. I'm sure that the Linux kernel already has rules as to naming conventions, header file control etc... More could be created to regulate good usage of C++ in a kernel environment.
Process Explorer will show you the threads in each process, complete with cpu time counters and stack trace. Looking at the mozilla process on my computer, it has 10 threads. However, only one of those threads has more than 1 second of total CPU time.
The main thread has spent 5:30 mins total CPU time. It is the message queue worker thread for all the windows. It spends its time in mozilla.exe. Three threads are waiting in nspr4.dll. (netscape something) One has spent 0 cpu time and is waiting in wdmaud.drv. One keeps asking for the system time some 500 times a second (context switch delta about 1000/sec) from winmm (maybe a Windows sound worker?) One is at 0 time with status Wait:DelayExecution And there are 3 LPC worker threads that have all spent 0 CPU time on status Wait:WrLpcRecieve. I assume these were created by and for the win32 subsystem. It is possible that other meaningful threads once existed, but have exited (and so are not displayed), but I doubt it.
The bottom line: Mozilla has only one meaningful thread. The rest are contingency support workers, probably created by libraries. As FireFox is based on Mozilla, I would assume it is the same. More CPUs won't help Mozilla's performance in the least.
There is a big difference between having multiple threads and processes and having multiple active, working threads. What are your firewall, virus scanner, instant messenger and email programs actually doing in the background? Waiting. The firewall is waiting for trafic and then does a trivial amount of processing. The virus scanner is a good example, if you are currently running a scan, although it may reach a bottleneck on the disk drive instead of the CPU. The instant messenger waits for incoming messages and does trivial processing on them. Same with the email program.
Most (current) background apps use so little processing power as they work, having an extra processor will reduce the other CPU's load by a negligable amount. The overhead for synchronizing multiple CPUs may even outweigh the benefits. Most of these apps use so little CPU power that you could use a cooperative multi tasking system without noticible loss in responsiveness.
I would say that Joe Average does not use multiple apps that actually tax the CPU. There is at most 1 program, such as a game, running in the foreground that would use most of the CPU's capacity. Joe would have to run at least 2 of these apps to take advantage of 2 cores/processors.
Are you saying that a system isn't multiuser unless it supports multiple GUI sessions? This would mean that Linux isn't multiuser unless you are running X Windows. No, this isn't the case as there were multiuser computers before network GUIs. Windows NT has included a Telnet server since at least 3.51; you can have as many users logged on (and working) as you want, with any edition of the OS. I personally use sshd with cygwin on my computers, and I have no problems with that for multiple users. Multiuser means that the system can have multiple active processes running in the security context of different users. NT has always supported this.
BTW: the first version of TS was NT4 TSE, and the first Citrix WinFrame was on NT 3.51.
If IE should never be used on production servers, why is IE so heavily integrated into the shell environment in which the server runs?
There really isn't a good reason, but there is an explination. It goes back to the very first version of NT: 3.1. Since then and up to Win2k, the server and workstation versions of Windows use exactly the same binaries, with a few extras for server and a flag in the registry. This meant that the same exact patches could be applied to both. It was convenient because the server would provide the exact same environment that the workstations provided. Windows makes its money by being compatible. MS says it plans to fork the server and workstation codebases in the future: ws2k3 does not use the same binaries as XP does, it's not even the same version of NT (XP is 5.1 and 2k3 is 5.2). The shell is there on server in case the user runs some kind of app that depends on it. It provides a unified Windows environment.
OH and last time I checked, many Linux distros install a shell environment, with a web browser, on a generic server install.
BTW, to say that the integration of IE in Windows is somehow equivalent to the integration of Konquerer in KDE is rather ridiculous.
You can remove all traces of Konqueror, not just the lanucher but all the HTML rendering and stuff, without breaking KDE? Can you have KDE without any web browser components?
It is trivial to entirely replace one browser with another on a GNU/Linux system. Eradicating all traces of IE on MS Windows machines is nowhere near as simple.
You can replace the shell with an entirely different one if you want on Windows. No, it isn't as easy since MS doesn't provide an uninstaller: you have a good point. It is possible; see nLite or LitePC. If you remove all traces of IE, it will break the shell, though. And breaking the shell will break any apps that depend on the shell, just like removing KDE would break KDE apps that depend on it.
So why is IE integrated into the kernel that the server is running on top of?
Internet Explorer has never been, isn't now and never will be integrated into the kernel. It does not run in kernel mode. The only thing that IE is integrated in is the shell environment and what Microsoft calls the "Windows Expierence". This integration with the 'expierence is the excuse they used to say that it had to be a part of Windows; it's a marketing reason, not a technical one.
The Windows shell environment is like what KDE is on Linux, and IE is integrated into it like Konqueror is integrated into KDE. The kernel has nothing to do with it.
You give all your TS users admin access? That's the problem; running it as admin. The OP specifically said web browsing + admin = stupid. The users can't do anything to the machine without admin access; IE or not.
You can also have the users use a different shell, and a different web browser if it makes you feel better. Also, 2003 has a special lock down mode for IE.
Hmmm. I had Google search for "TIMI recompilation" and I found this interesting page. It supports what you are saying.
I wonder how the TIMI works. It does mention that
Many customers needed merely to save their programs off their CISC machines and restore them on their new RISC machines, and the programs ran as fully 64-bit programs.
This saving and restoring-- I wonder if the files are changed by this process; converted from CISC machine code to PPC RISC. If this is true, then it would be like the dynamic recompilation (albeit with the dynamic part somewhat unnecessary) used by some emulators and VMs. Either that, or the code was never in native machine language; it was just interpreted on demand like Java bytecode. I guess if the CPU had support to natively execute different instruction sets (I think the Alpha can do this to some extent, IDK about PPC), that would work (although it wouldn't be portable to CPUs without this capability). I may be ignorant, but I'm not aware of a fourth way to make this happen. It also mentions that
An iSeries program has no knowledge of the underlying hardware; this knowledge remains entirely within the SLIC. This means that when the processor technology changes, IBM can rewrite the SLIC components that are aware of those technology changes and thus preserve the integrity of the machine interface.
This implies that much of the operating system (more than four million lines) is not so hardware-indepenent if parts of it need to be rewritten due to 'technology changes'. Perhaps the SLIC code has only source-level portability?
If you compile programs to a portable code that has no knowledge of the hardware it runs on, it sounds an aweful lot like Java bytecode, or.NET IL to me. These can be made into native code via a JIT regardless of CPU architecture, just like user *PRGs. Heh, I wonder if the code format is openly available: it would make a third-party AS/400 program environment possible, even easy, thanks to the portibility.
That was my intial point, that it does not.
If MS had gone the AS/400 route, then many binaries ( those not involved in the HAL ) *would* be interchangable across platforms.
OK I guess I misundestood; I thought you were saying that the NT HAL could do that. Maybe you were referring to the '400 TIMI, and something like it that could have been for NT?
I guess Microsoft used only source level portibility since that was the state of the art for PCs at the time and not enough people on the dev team wanted to do it any other way.
I had an AS/400 and two RPG IV classes at college last year; that's the extent of my expierence. Really, I'm quite impressed with IBM's backwards compatibility and ability to move to new platforms with zero problems. Part of this is due to good planning in the first place, like designing the TIMI.
I can undestand that it is hard to get details on the inner workings of some of these things since IBM is even more protective of its operating system secrets than Microsoft is.
Windows Installer is in fact trying to do exactly that. If done properly, you don't need admin privledge to install signed MSI packages; the Windows Installer service runs as SYSTEM and can conduct the install itself. Currently, it works best on a domain; the domain admins make a list of approved packages and normal users can install them on their computers through add/remove programs.
OK, but my point is that as a compiler writer or whatever, my target properly would be that abstraction layer, not the underlying chip's native language. Of course, *something* has to be in the native format for the chipset of the machine, but not your user applications.
The only kind of abstraction layer I know of that lets you compile into a cpu independent format is a VM. The generated machine language is for a virtual CPU that is emulated in software by native code. The abstraction layer in this case is an interpreter that executes instructions targeted for it. The interperter is written in native code. Something has to translate this generic format into a form the CPU can understand since the CPU still has to process the data at some point.
I could be wrong, but I didn't think that the AS/400 works this way. All it provides is source-level compatibility between programs; if you move to a new platform you just have to recompile.
It doesnt *have* to be only for kernal mode. Granted that would be more work, and probably more overhead.
There is nothing that you could DO with it in user mode. You can't access the hardware devices directly from user mode: the in/out instructions are illegal at ring3, device memory is never mapped, you can't handle interrupts... The NT HAL exists to provide generic helpers for some of these services and if you can't use the services in the first place, those helpers would be quite useless.
You can't change the IRQL from passive in user mode: one page fault-> bluescreen. You can't handle interrupts for the same reason; interrupts raise the IRQL. You can't map device memory, so no DMA. You can't access IO ports. If you could use the HAL from user mode, just what functions would you call in it?
That's part of my point. On the AS/400, the abstraction layer *does* provide CPU portability.
So you DO understand that the NT HAL doesn't provide CPU portability alone? The HAL is only one component thas has been compiled specifically for a CPU. You can't just take atapi.sys (or any other binary, kernel mode or not) from say the PowerPC build and expect it to run on your x86. All of those files were compiled specifically for their specific CPU arch.
OTOH, the HAL and part of the kernel do provide CPU portability on a source code level, so that drivers don't have to contain CPU specific source code. They still have to be compiled seperatly for each CPU type, though. The operating system provides source-level portability to user mode apps, so the HAL is unnecessary. It is entirely possible to write a Windows app that, without source modification, can be compiled to run on Win16, Win32(PPC, MIPS, x86, Alpha), and Win64(Itanium, 86-64). Different binaries for each, but the same source code. Just like you can create a POSIX app that will compile on Solaris-Sparc, AIX-PPC, HP-UX, FreeBSD-x86, NT-Alpha, NT-x86. POSIX provides source-level portability too.
If the HAL in NT was there for everything, all the mentioned issues would not have been there.
The NT HAL abstracts IO ports, interrupts including masking (through software IRQLs), multi CPU enum and control, DMA, the blue screen, idle processing, non PnP device enumeration, clock and timer abstraction, and IO port access. Look at hal.dll's exported functions. The HAL abstracts basic functions of the computer's chipset that the kernel needs to function. ACPI provides most of the functions now. The HAL does not make the system portable across CPU archs alone. The most it does is play a part in abstracting IRQ masking with IRQLs. The HAL, the kernel and all the other binaries are still compiled to a specific CPU. The only thing that the HAL communicates is the kernel, and drivers running in kernel mode. It is completely irrelevant to user mode programs since user mode programs cannot ever access hardware directly. The most and only hardware that a user mode app can be compiled is the CPU itself.
In NT, the HAL was *only* for the OS.
The NT HAL is for anything in kernel mode. It would be useless to user mode programs.
On the AS/400, nothing touched the real machine, OS or Apps.
What you are describing sounds like a VM environment, like Java. It's not.
On an AS/400, there are only two ways to get binary code onto the system: as a system library installed from a very trusted source, and thru a trusted compiler on the system. Early '400s CPUs didn't have protected memory, so this was the method to provide a secure system. Still, binary code does in fact exist. You have to compile programs to a *PRG file. Those *PRGs are trusted to play nice given kernel mode equivalent access since they came from a trusted source. IIRC, the TIMI (technology independent machine interface-- the HAL) was a static/code library that abstracted different architectures to make porting of the core libraries and compilers easy.
If the HAL in NT was there for everything, all the mentioned issues would not have been there.
The NT HAL is there to abstract certain functions that drivers and the kernel need to use regardless of the machine's chipset. It does not provide CPU portability.
.NET apps are compiled to an intermediate language (IL) that is portable across architectures, like Java bytecode. When the program is loaded, the IL is compiled into native code on demand (by the JIT). Currently, executables also contain a pre-compiled version for x86.
I'm not saying by any means that Microsoft is first at this or that their method is perfect: only that MS does in fact have a plan to make it easy to create cross-platform apps where the developers don't have to worry about the target platform much.
However, at the end of the day these platforms couldn't run the software people wanted without jumping through hoops like Digitals binary translator. No apps, no interest.
Back then, you couldn't run mainstream apps on another CPU arch without recompiling or using an emulator. VMs like Java were still too new. Now there is.NET which can be compiled to IL very easily and IL can be compiled to whatever arch on demand by the end user transparently. Microsoft is pusing.NET hard; 'unmanaged' code is considered depreciated, even now. And since it's Microsoft.NET, the not-invented-here syndrome doesn't apply (like it does with Java)
Microsoft could concievably move to a new CPU architecture once mainstream Windows programming is done on.NET and use a transparent emulator for legacy x86 apps. It would even pressure people to upgrade since old x86 apps will be slow compared to newer.NET ones. Longhorn is supposed to have tons of.NET in it; maybe they will use it for this.
Which site was this? Post it. I have a hard time believing that the operating system crashed. IE is just another user mode program; it can't do anything special to crash the system.
Oh I know you are going to tell me he is visiting the wrong web sites right?
I won't tell you that. If you are right, then you have an excelent example of IE sucking. You should be able to view any websites without this happening.
I'm glad modern linux distros automatically prompt for the root password when needed.
This is a nice feature; I wish that Windows did the same.
As far as I'm concerned (on the windows side), having to open the entire shell (explorer) as admin in order to run a certain program (e.g., control panel) seems like bad design.
You can thank shell integration for this. Everything in the shell (including the control panel) likes to use the same libraries and run in the same process. Control.exe just signals the explorer process to open the control panel and exit. It goes back to the days of Win95 when extra processes cost precious memory; 95 had to run comfortably in FOUR megabytes. Unfortunately, this design choice was never reversed.
I would at least like to see the commandline version of runas work as well as su does in linux.
Take a look at SU/SUD. I think it works as good as su does on Linux. Yeah, it's third party, but it works.
Yeah, Runas does suck for scripting. Try SUD; it is great for this. You can create 'cfg' files that only run a specific program under a specific user without divulging the account's password. It's kinda like setuid. From the docs:
First create a SU configuration file using the following syntax :
su -u administrator -p - -c c:\temp\setup.exe -C c:\temp\su.cfg -S
and enter administrator's password ; this yields the creation of a crypted SU configuration file
c:\temp\su.cfg.
Now, any user who has right to run su.exe and read c:\temp\su.cfg can enter the following command
su -C c:\temp\su.cfg
This command starts c:\temp\setup.exe in the security context of your local administrator, but the
user ignores the password !
Include the fact that most developers never take the multi-user environment into consideration.
This IS a serious problem. It really is the fault of the developers, though. Usually there are case-by-case workarounds available. It isn't pretty but it can work.
Here's my example. I will not state a specific app since RunAs works for some, but not most apps out there. Run an app with RunAs. It loads with Administrator priviledges. It will then try to load settings stored in Documents and Settings. There's your problem. Most apps attempt to load stuff off of the current user account, not the account you RunAs'ed. So the app loads with Admin priviledges. But it loads data from the current logged-in account. To Joe Public, these makes the Windows look even more broken... which, as a true multi-user platform, it is.
/profile : Loads the user's profile./profile is the default.
/no profile : Specifies that the user's profile is not to be loaded. This allows the application to load more quickly, but it can also cause a malfunction in some applications.
This implies that loading the specified user's profile is default. In any case, the behavior can be controlled by a command line parameter. For PsExec, use the -e flag to force the profile to be loaded. SUD always tries to load the specified user's profile for the new process.
I would think that Joe User would want the same profile loaded regardless of priveledge level to work around broken apps: he wants to run app XYZ but XYZ requries admin acccess. Joe User doesn't care that this app requires admin; he just wants it to work. Joe doesn't want to keep seperate document directories because of this silly detail (silly to Joe). It would be more intutiave if all the apps, admin or not, used the same profile since the same real user is using both.
That's funny earlier this year I got malware all over one of my machines because I was using IE.
Name the malware package. Where can I find it? I want to try getting infected by it. I have VMs I can use safely for this. I'm not saying it's impossible, but I would appreciate a specific example.
... has complete access to all the resources on your machine...
This would only be true if you were running the browser as admin. Don't do that.
You are kidding yourself if you think that a lack of ignorance is reasonable protection against flaws in any software.
It is reasonable protection if those flaws can be worked around. I submit that Windows's flaws are avoidable.
If the server gets compromised (and, yes, NNTP and SMTP are listed amongst the systems with holes) then you could very easily end up with hostile code on your machine, no matter how updated it may be.
So you download programs and give them privledged access on your computer based solely on the server they came from? That kind of trust should require you to trust that the server admins keep their computers up to date and would be aware of external control. You ought to have spoofing protection (mutual authentication) or it could all be for naught; you might not even be talking to your trusted server. This is not unique to Windows; it should apply to all secure networked environments.
As far as Linux is concerned, a properly configured Linux box is relatively secure, even if the applications have holes. This is because you can run most servers under restricted user IDs and/or in chroot-ed environments. This means that someone breaking into a server application can't really go anywhere.
The same is true on Windows. Services can be run under the security context of any user account with the SE_SERVICE_LOGON_NAME privilege. A service running under a normal user would be unable to comprimise the system without first exploiting a local kernel vulnerability. Can you name any current NT kernel vulns?
Finally, Linux has some extensions which make it bullet-proof against many types of attack. Mandatory Access Controls and filesystem ACLs mean that you can have an extremely fine-grained level of control over who can do what. This means that if some server software has a user ID of N, but N only has read permissions on N's files, then compromising the server can't even allow an attacker to modify the files they supposedly own.
NTFS has always had file ACLs. You can easily do everything you describe with them.
All this means that Linux applications don't need to be that secure. The security is provided. It is helpful if they ARE secure, but it's not essential. With Windows, this isn't the case.
How's this? Windows NT has all the local security that a standard unix does. Use it.
The level of security isn't that great, and as more and more is integrated into the kernel, the vulnerabilties within any given application become ever-more dangerous to other parts of the OS.
What, specifically, are you talking about 'integrated into the kernel'? First, are you referring to things running in kernel mode or things that are actually part of the kernel itself? Can you provide an example of something integrated in the kernel that shouldn't be there, or better yet: something that is causing a security vulnerability?
There IS an offical distrobution. There are specific people that decide what code goes into this package. They do have standards. I can see it as a practical problem for the Linux kernel if all the current devs are used to C only, but that really isn't a good reason to not use C++ in general for kernels. The community has changed in the past; this wouldn't happen overnight.
C is plenty possible to abuse, espescially in kernel code. I've heard about all kinds of kernel patches that were not put in the main distro because they were messy/unstable without serious clean-up.
Anyways:
Objects x and y of type SomeType are created with the default constructor.
You call the assignment operator on y with an argument of 3: you should have initialized y with 3 when you declared it.
The addition operator is called on y with an argument of 5. The return value of this function will likely become a temporary, assuming a normal use of this operator.
The assignment opeator is called on x with a parameter from the return value of the above function. You should have initialized x to this value instead of using assignment (assuming a sane definiton of the assignment operator).This is only true if you have no standards on the code in your classes. Done correctly, it does not matter how the functions work as long as they are correct and their dependencies are known (when needed).While it is possible to make the "=" and "+" operators do stupid things like output "HI" to the console, that is delibrate obfucation of code; abuse of the language. Operator overloading should only be used when it provides simple and intuitive convenience to code. If SomeType.operator =() doesn't do assignment then it shouldn't be overloaded. If SomeType doesn't make sense to use + with then that souldn't be overloaded either. You could easily make it a code policy that operators cannot do anything more than trivial processing: that they cannot allocate/free memory, access anything outside the class or parameters, or raise exceptions. Any deviation from this policy would represent invalid code. That way, you wouldn't need to know how the the operators work, just that they do what is obvious without complications. This is the basis of abstraction. You face the same need for standards for writing ANY function.
Operators, like many things can be bad if used incorrectly. So can pointers.
A good use of operator overloading is the creation of new types. Take a 128 bit integer: most compilers do not have a primitive type for it. In C, you would have to make specialized handling every time you wanted to use the number; a typedef would be out of the question. You would have to maintain a seperate code base for this; you would have to make sure every change is replicated across both sets of code. With operator overloading in C++, you simply overload the operators to do the same thing they would do with a primitive type. The new type can be used with exactly the same code as an int64 and the meaning will be just as obvious.If you read my earlier post, you would know that I never advocated the use of exceptions; in fact, I try to avoid them.
C++ is every bit as detirministic as C is. It is one of the language's biggest strengths. Order of evaulation is exactly the same, BTW.
I guess this would work pretty good, although you would have to maintain functions to access any data inside of inner whereas you could get to it directly with public. That was my point, that public/private is more convenient than handles. It lets you concentrate more on important things rather than wasting time writing glue functions, as you must to access any properties of a handle.Kernel code already has a million ways to do bad things. Having a different language won't make it much worse. Done properly, C++ can help you write better code that is MORE resilient to idiocy, not less, using namespaces, new types by overloading, smart/safe pointers, templates, member protection...
Having developers that don't follow rules and write sloppy code is a much bigger problem than a change of language can fix. Bad developers will write bad code no matter the language. There are plenty of rules you can break to make bad code in C too. There are plenty of rules in kernel code that bad developers will break, too. I can't imagine that C++ would make that big a difference; there will still be programmers that disregard the rules.
Don't like exceptions? Don't use them. C++ doesn't require you to. Personally, I don't use them unless I have to interface with other code that does. I usually compile with exception support off.
Is allocating memory in a constructor likely to cause problems? Make it a standard code practice for your project to never cause non-explicit memory allocation. Destructors can be forced to run at a specific time with delete or by using forced scopes (use {} around the lifetime of the local var). Copying objects in a standard way is easy to do, espescially if you always pass classes (structs) as references or by pointer.Are you saying that C++ always uses more memory than C? That's silly. If you can't call memory allocation functions right now, then allocate things on the stack. Make sure that the objects you create and the functions you call don't alloc either. You would have to make sure the functions were safe in C too.Ok, so don't use the heap. There is no reason that C++ needs to use the heap; everything can be allocated on the stack. Just like C.Assembly isn't too nice if you care about portability. It also depends on the architecture about how nice and simple it is. Segmented memory in assembly can be a nightmare.
Don't use the STL implementation of linked lists if you don't like it. Done properly, you could use templates for even more than that, like different index sizes for a filesystem; a 32 bit version for small volumes, a 64 for large volumes and a 128 for extremely large volumes. Since there is no primitive 128 bit type, C++ lets you override operators to create a new type that acts exactly like a primitive. This word size would be a template parameter of the filesystem class; a static version created for 32, 48, 64 and 128 bit or whatever. One code set, no redundancy. Remember the Sun story about a 128 bit filesystem? It could be as easy as recompilation!
How about namespaces? These would be very useful in the kernel, IMHO.
Member functions are nice for associating a function with an object.
Private data members allow you to put data in a structure that outside code doesn't need to know about so you can change it later without breaking compatibility. Documentation can do it too, but this can enforce it.
I bet there could be some good uses for smart pointers.
The fact that a language has a feature does not obligate you to use it. You can use code standards in your project that set sane regulations for the code in the project. You need standards for any a sizable project in ANY language, including C. I'm sure that the Linux kernel already has rules as to naming conventions, header file control etc... More could be created to regulate good usage of C++ in a kernel environment.
Process Explorer will show you the threads in each process, complete with cpu time counters and stack trace. Looking at the mozilla process on my computer, it has 10 threads. However, only one of those threads has more than 1 second of total CPU time.
The main thread has spent 5:30 mins total CPU time. It is the message queue worker thread for all the windows. It spends its time in mozilla.exe.
Three threads are waiting in nspr4.dll. (netscape something)
One has spent 0 cpu time and is waiting in wdmaud.drv.
One keeps asking for the system time some 500 times a second (context switch delta about 1000/sec) from winmm (maybe a Windows sound worker?)
One is at 0 time with status Wait:DelayExecution
And there are 3 LPC worker threads that have all spent 0 CPU time on status Wait:WrLpcRecieve. I assume these were created by and for the win32 subsystem.
It is possible that other meaningful threads once existed, but have exited (and so are not displayed), but I doubt it.
The bottom line: Mozilla has only one meaningful thread. The rest are contingency support workers, probably created by libraries. As FireFox is based on Mozilla, I would assume it is the same. More CPUs won't help Mozilla's performance in the least.
There is a big difference between having multiple threads and processes and having multiple active, working threads. What are your firewall, virus scanner, instant messenger and email programs actually doing in the background? Waiting.
The firewall is waiting for trafic and then does a trivial amount of processing.
The virus scanner is a good example, if you are currently running a scan, although it may reach a bottleneck on the disk drive instead of the CPU.
The instant messenger waits for incoming messages and does trivial processing on them. Same with the email program.
Most (current) background apps use so little processing power as they work, having an extra processor will reduce the other CPU's load by a negligable amount. The overhead for synchronizing multiple CPUs may even outweigh the benefits. Most of these apps use so little CPU power that you could use a cooperative multi tasking system without noticible loss in responsiveness.
I would say that Joe Average does not use multiple apps that actually tax the CPU. There is at most 1 program, such as a game, running in the foreground that would use most of the CPU's capacity. Joe would have to run at least 2 of these apps to take advantage of 2 cores/processors.
And on Windows (2000 or later) it would be
jobprc suspect.exe -prclimit 100
Or you could set your shell to start as jobprc explorer -prclimit 100.
Are you saying that a system isn't multiuser unless it supports multiple GUI sessions? This would mean that Linux isn't multiuser unless you are running X Windows.
No, this isn't the case as there were multiuser computers before network GUIs. Windows NT has included a Telnet server since at least 3.51; you can have as many users logged on (and working) as you want, with any edition of the OS. I personally use sshd with cygwin on my computers, and I have no problems with that for multiple users.
Multiuser means that the system can have multiple active processes running in the security context of different users. NT has always supported this.
BTW: the first version of TS was NT4 TSE, and the first Citrix WinFrame was on NT 3.51.
OH and last time I checked, many Linux distros install a shell environment, with a web browser, on a generic server install. You can remove all traces of Konqueror, not just the lanucher but all the HTML rendering and stuff, without breaking KDE? Can you have KDE without any web browser components?You can replace the shell with an entirely different one if you want on Windows. No, it isn't as easy since MS doesn't provide an uninstaller: you have a good point. It is possible; see nLite or LitePC. If you remove all traces of IE, it will break the shell, though. And breaking the shell will break any apps that depend on the shell, just like removing KDE would break KDE apps that depend on it.
- So why is IE integrated into the kernel that the server is running on top of?
Internet Explorer has never been, isn't now and never will be integrated into the kernel. It does not run in kernel mode. The only thing that IE is integrated in is the shell environment and what Microsoft calls the "Windows Expierence". This integration with the 'expierence is the excuse they used to say that it had to be a part of Windows; it's a marketing reason, not a technical one.The Windows shell environment is like what KDE is on Linux, and IE is integrated into it like Konqueror is integrated into KDE. The kernel has nothing to do with it.
You give all your TS users admin access? That's the problem; running it as admin. The OP specifically said web browsing + admin = stupid. The users can't do anything to the machine without admin access; IE or not.
You can also have the users use a different shell, and a different web browser if it makes you feel better. Also, 2003 has a special lock down mode for IE.
I wonder how the TIMI works. It does mention that
- Many customers needed merely to save their programs off their CISC machines and restore them on their new RISC machines, and the programs ran as fully 64-bit programs.
This saving and restoring-- I wonder if the files are changed by this process; converted from CISC machine code to PPC RISC. If this is true, then it would be like the dynamic recompilation (albeit with the dynamic part somewhat unnecessary) used by some emulators and VMs. Either that, or the code was never in native machine language; it was just interpreted on demand like Java bytecode. I guess if the CPU had support to natively execute different instruction sets (I think the Alpha can do this to some extent, IDK about PPC), that would work (although it wouldn't be portable to CPUs without this capability). I may be ignorant, but I'm not aware of a fourth way to make this happen.It also mentions that
- An iSeries program has no knowledge of the underlying hardware; this knowledge remains entirely within the SLIC. This means that when the processor technology changes, IBM can rewrite the SLIC components that are aware of those technology changes and thus preserve the integrity of the machine interface.
This implies that much of the operating system (more than four million lines) is not so hardware-indepenent if parts of it need to be rewritten due to 'technology changes'. Perhaps the SLIC code has only source-level portability?If you compile programs to a portable code that has no knowledge of the hardware it runs on, it sounds an aweful lot like Java bytecode, or
Heh, I wonder if the code format is openly available: it would make a third-party AS/400 program environment possible, even easy, thanks to the portibility.
- That was my intial point, that it does not.
OK I guess I misundestood; I thought you were saying that the NT HAL could do that. Maybe you were referring to the '400 TIMI, and something like it that could have been for NT?If MS had gone the AS/400 route, then many binaries ( those not involved in the HAL ) *would* be interchangable across platforms.
I guess Microsoft used only source level portibility since that was the state of the art for PCs at the time and not enough people on the dev team wanted to do it any other way.
I had an AS/400 and two RPG IV classes at college last year; that's the extent of my expierence. Really, I'm quite impressed with IBM's backwards compatibility and ability to move to new platforms with zero problems. Part of this is due to good planning in the first place, like designing the TIMI.
I can undestand that it is hard to get details on the inner workings of some of these things since IBM is even more protective of its operating system secrets than Microsoft is.
Windows Installer is in fact trying to do exactly that. If done properly, you don't need admin privledge to install signed MSI packages; the Windows Installer service runs as SYSTEM and can conduct the install itself. Currently, it works best on a domain; the domain admins make a list of approved packages and normal users can install them on their computers through add/remove programs.
- OK, but my point is that as a compiler writer or whatever, my target properly would be that abstraction layer, not the underlying chip's native language. Of course, *something* has to be in the native format for the chipset of the machine, but not your user applications.
The only kind of abstraction layer I know of that lets you compile into a cpu independent format is a VM. The generated machine language is for a virtual CPU that is emulated in software by native code.The abstraction layer in this case is an interpreter that executes instructions targeted for it. The interperter is written in native code. Something has to translate this generic format into a form the CPU can understand since the CPU still has to process the data at some point.
I could be wrong, but I didn't think that the AS/400 works this way. All it provides is source-level compatibility between programs; if you move to a new platform you just have to recompile.
- It doesnt *have* to be only for kernal mode. Granted that would be more work, and probably more overhead.
There is nothing that you could DO with it in user mode. You can't access the hardware devices directly from user mode: the in/out instructions are illegal at ring3, device memory is never mapped, you can't handle interrupts... The NT HAL exists to provide generic helpers for some of these services and if you can't use the services in the first place, those helpers would be quite useless.You can't change the IRQL from passive in user mode: one page fault-> bluescreen. You can't handle interrupts for the same reason; interrupts raise the IRQL. You can't map device memory, so no DMA. You can't access IO ports.
If you could use the HAL from user mode, just what functions would you call in it?
- That's part of my point. On the AS/400, the abstraction layer *does* provide CPU portability.
So you DO understand that the NT HAL doesn't provide CPU portability alone? The HAL is only one component thas has been compiled specifically for a CPU. You can't just take atapi.sys (or any other binary, kernel mode or not) from say the PowerPC build and expect it to run on your x86. All of those files were compiled specifically for their specific CPU arch.OTOH, the HAL and part of the kernel do provide CPU portability on a source code level, so that drivers don't have to contain CPU specific source code. They still have to be compiled seperatly for each CPU type, though. The operating system provides source-level portability to user mode apps, so the HAL is unnecessary. It is entirely possible to write a Windows app that, without source modification, can be compiled to run on Win16, Win32(PPC, MIPS, x86, Alpha), and Win64(Itanium, 86-64). Different binaries for each, but the same source code. Just like you can create a POSIX app that will compile on Solaris-Sparc, AIX-PPC, HP-UX, FreeBSD-x86, NT-Alpha, NT-x86. POSIX provides source-level portability too.
- If the HAL in NT was there for everything, all the mentioned issues would not have been there.
The NT HAL abstracts IO ports, interrupts including masking (through software IRQLs), multi CPU enum and control, DMA, the blue screen, idle processing, non PnP device enumeration, clock and timer abstraction, and IO port access. Look at hal.dll's exported functions. The HAL abstracts basic functions of the computer's chipset that the kernel needs to function. ACPI provides most of the functions now. The HAL does not make the system portable across CPU archs alone. The most it does is play a part in abstracting IRQ masking with IRQLs. The HAL, the kernel and all the other binaries are still compiled to a specific CPU. The only thing that the HAL communicates is the kernel, and drivers running in kernel mode. It is completely irrelevant to user mode programs since user mode programs cannot ever access hardware directly. The most and only hardware that a user mode app can be compiled is the CPU itself.- In NT, the HAL was *only* for the OS.
The NT HAL is for anything in kernel mode. It would be useless to user mode programs.- On the AS/400, nothing touched the real machine, OS or Apps.
What you are describing sounds like a VM environment, like Java. It's not.On an AS/400, there are only two ways to get binary code onto the system: as a system library installed from a very trusted source, and thru a trusted compiler on the system. Early '400s CPUs didn't have protected memory, so this was the method to provide a secure system. Still, binary code does in fact exist. You have to compile programs to a *PRG file. Those *PRGs are trusted to play nice given kernel mode equivalent access since they came from a trusted source. IIRC, the TIMI (technology independent machine interface-- the HAL) was a static/code library that abstracted different architectures to make porting of the core libraries and compilers easy.
- If the HAL in NT was there for everything, all the mentioned issues would not have been there.
The NT HAL is there to abstract certain functions that drivers and the kernel need to use regardless of the machine's chipset. It does not provide CPU portability.Like .NET, IL and the JIT?
.NET apps are compiled to an intermediate language (IL) that is portable across architectures, like Java bytecode. When the program is loaded, the IL is compiled into native code on demand (by the JIT). Currently, executables also contain a pre-compiled version for x86.
I'm not saying by any means that Microsoft is first at this or that their method is perfect: only that MS does in fact have a plan to make it easy to create cross-platform apps where the developers don't have to worry about the target platform much.
And since it's Microsoft
Microsoft could concievably move to a new CPU architecture once mainstream Windows programming is done on
In any case, the behavior can be controlled by a command line parameter.
For PsExec, use the -e flag to force the profile to be loaded.
SUD always tries to load the specified user's profile for the new process.
I would think that Joe User would want the same profile loaded regardless of priveledge level to work around broken apps: he wants to run app XYZ but XYZ requries admin acccess. Joe User doesn't care that this app requires admin; he just wants it to work. Joe doesn't want to keep seperate document directories because of this silly detail (silly to Joe). It would be more intutiave if all the apps, admin or not, used the same profile since the same real user is using both.