- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
Admin
Do Until False = True?
Admin
Ok - depending on what portion of the files are to be deleted, and how many are in the directory, this might or might not be stupid.
Why is this a problem? When a variable gets set to a new object, shouldn't the old one be garbage collected?
As far as being inside the loop or not, if the idea is that the .ini file can be changed without restarting the "service", it looks like all the code belongs in there.
Why, specifically, is it a bad idea? Leaving aside the issue of actually making it a proper service (which could have been done in VB), is there any reason not to use the most familiar and convenient tool at hand to implement this small program?
Admin
It seems that the whole "page fault" thing is really trying to imply that this was a major resource (CPU? Mem? Disk?) hog. (This might be TRWFT.)
This story is missing quite a bit of context about the size of the directory and file list, and "pseudo codes" away a lot of what's going on.
If the goal is to remove a handful of files from a directory with thousands, maybe there is a WTF here. But assuming a smallish directory to scan through, it wouldn't seem to be a problem.
Although "do while true" would be a major style improvement, it wouldn't have any bearing on performance.
Admin
Oh I get it, TRWTF is that the loop runs eternally until the flag blnLoopEternal is set to true.
Should be the other way around. Run until blnLoopEternal is false, obviously.
Admin
Ok..seems like we have Page Faults, SEGFAULTS, General Protection Faults but what we really need are My Faults and Your Faults...This one is clearly Your Fault ;-)
Admin
I hope you aren't actually any sort of programmer. Let's do a quick run through:
There's a GoTo in there.
The entire thing is an infinite repeating loop.
VB6.
GoTos are bad. Yes, even for error handling. Bad. Stop it.
This has got to be the worst possible way in terms of efficiency to code this, and it definitely has a very real negative performance impact. You could of actually made a service, or even just set it up as a windows scheduled task, but an infinite repeating loop? This isn't a PIC.
VB6 is slow, messy, and has terrible style. A batch script would of actually been better. Ideally a quick C or C++ program. Java at least would of been neater, even if no faster.
It takes maybe 20 minutes to write a flexible service to do something about this complex. The article notes it took the developer in question "several days".
Admin
It seems to me that the real WTF here is Windows Services.
Not to sound like a Linux bigot, but in Linux, to make a service you write a program just like any command line program, then run it just like you would run any command line program, except you add an ampersand to the end of the command line. That is, the "Linux Service API" is "type an ampersand after the program name". If you like you can create shell programs to start, stop, and restart the app. But that's purely optional.
In Windows, to create a service you have to implement an API entirely separate from what you would write for any other program. Why? It's just a ton of junk dumped on top of the Windows developer.
Admin
I think you mean, Do Until False = FileNotFound
Admin
Even at that. Say the directory has 20 files that should be kept and a 1000 that should be deleted. Assuming that there is no pattern to the file names, i.e. you can't say "delete tmp*.txt" or something like that, than the only way to delete them is to identify them one by one and delete each in turn. So it's difficult to see how the program could really be made more efficient.
Admin
GoTo's are not inherently bad on their own. Modern constructs merely mask the use of them a lot of the time. Furthermore, in VB1-6, that was the standard way of performing error handling as VB6 did not have try/catch/finally. You either do On Error GoTo (|GoSub) or there was no error handler in that function.
Making it a service or scheduled task doesn't fix the loop, which sleeps for a minute anyhow, releasing resources and letting other things do their thing. A basically infinite repeating loop is how the Windows message pump works in any Windows application with a UI. I suppose that's stupid, too.
VB6 was not slow, didn't have to be messy (this code is far from it), and style is subjective. I don't care for the overly verbose style of BASIC myself, either. If the thing were written in Java, it would probably be as fast or faster than the similar C program but wouldn't be able to (easily) run as a service. Another choice would be .net, where it would be trivial to write a service and be as fast or faster than the equivalent C program (we're talking about blocking I/O here - the speed of the actual compiled code is a barely a measurable percent of the overall speed).
The thing to do would probably have been to set up a watcher for the directory (ReadDirectoryChangesW or FileSystemWatcher in .net), see if the file (or files) matches the list that was just written, and delete it if so, otherwise do nothing.
Admin
The default Windows app is a desktop GUI app. And while X is a joke, Windows can at least have pretty GUIs because of Microsoft's API choices and the hoops they make developers jump through.
Admin
I'll join the chorus of "what's the problem" here.
To summarize the objections raised to this program so far:
It uses VB6, and VB6 is an old language. Okay, so what? Is it adequate to handle the job? Yes. So if the programmer is comfortable with it, why not use it? It wouldn't be my choice, but if it does the job, who cares?
It has an infinite loop so there's no way to terminate the program. The article quotes the programmer as saying you could kill it by moving the ini file. I'd think a more direct way to kill it would be to use TaskManager. Clumsy and messy, but ... exactly how is it better to access Windows Services and click "stop" than to access Task Manager and click "terminate"?
It never frees the directory object for garbage collection. Yes it does: the next time through the loop when it reassigns the variable to a new directory object. Okay, there's the minor issue that it holds that directory object through the sleep, so it is probably using it for a couple of milliseconds, then it sits there wasting space for 60 seconds, then it destroys it and creates a new one that it used for a few milliseconds, etc. You could free up some system resources by fixing that.
It causes page faults. If you are using the correct terminology, then okay, that may be true: every time the sleep expires, it fires up again, and if it got swapped out of RAM, that would cause a page fault and a refresh from virtual memory. So what? That's what virtual memory is for. That's like saying that a progam is flawed because it periodically quits running for no good reason ... except that it's waiting for input from the user. If instead you made it a service or a cron job that ran every sixty seconds, then each time the timer clicked it would reload the program from disk. This way, each time the timer clicks it ... reloads the program from disk. I suspect that reloading a page from virtual memory takes less time than firing up a new process and loading an exe file, so this method is probably more time efficient. If you're constrained on virtual memory, maybe that's a problem.
So what's wrong with this program again? I don't know that I'd hold it up as a model that should be given an award, but it seems an adequate solution to the problem.
Admin
Running a process in the background (which is what the ampersand does) doesn't turn a process into a daemon, which is what would be the equivalent construct in Linux.
In Windows, the program just has to respond to a few API calls so that the service control manager can interact with it (e.g. to start up, shut down, etc.), similar to the way a proper daemon has a few set things to do (fork a child process, etc.). It's really not complicated.
Admin
I had to maintain a FORTRAN program once (it was a long time ago in a time where such languages were commonplace) such that every error condition whose cause originated with invalid data entered by the user was directed to one single location in the code. At that location was the line:
Addendum (2012-02-16 15:11): Sorry, should have been
Admin
Yeah! I would've used JScript.
Admin
Admin
Aha - I know what the problem is! There's no copyright header or amendment list.
And another one: the indenting is 3 spaces, when standard programming style is 4 as everybody knows.
Both issues are outrageous and require the programmer to be disciplined. Edna Krabappel in fishnets and leather basque with a whip, methinks ...
Admin
I said it in an earlier post, but I think I'll word it more directly this time.
I think that this program should have been implemented as a scheduled task instead of an infinite loop. I do not think using an infinite loop that can only be terminated by moving a file is an elegant, efficient, or intelligent solution.
If you think about the 1 minute sleep call, clearly the developer was attempting to force it to run at specified intervals; that is, he was trying to schedule it. Wouldn't it make more sense then to manage it as a scheduled task instead of having to go into the program itself, change the sleep call, and then recompile when the intervals need to be increased or decreased? Not only would that make the program easier to manage, but it would also remove the infinite loop. Moreover, you wouldn't have to browse your way into some random directory, and then delete a file just in case you need to terminate it (or end the task for that matter). That seems like a pain in the ass to me, and avoids a much better way to handle the process.
But that's just me, I guess. Maybe there isn't really a problem with it, but it seems very sloppy to me.
Admin
I'm not sure what is more disturbing...the leather basque or that you know how to spell "Krabappel".
Admin
That's the way you do generic error handling in VB6. It's hardly different conceptually than wrapping the whole loop in a "try/catch". If the thing blows up, drop to the cleanup code at the bottom. Granted it gets messy when you're only trapping errors over a few lines. VB's shortcoming, not the programmer's.
How is this inefficient? How would a service be any different? They both do something, wait, and do it again. If you made it a task, what do you think happens inside the scheduler? And, AFAIK, the scheduler would have the overhead of starting a new process evey pass through.Definitely lazy to not have a proper exit to the loop. But I wouldn't call it a WTF - the thing really isn't intended to ever stop.
VB6 was slow when there are controls being used. Sometimes painfully slow. When it is just straight code doing some processing, it is as fast as anything else that's compiled. Definitely faster than anything interpreted, provided the program isn't constantly being restarted, and maybe even then.
As far as messy and terrible style, that's in the eye of the beholder. I would argue that all the memory managment, pointers for a "byref" call, and hoop-jumping to deal with strings in C is much more messy, but C would be acceptable to programming snobs. The use of C and C++ for general application programming instead of something much more sane caused a decade of shitty software quality.
Granted, he's as slow as molasses going uphill in January, but I'm looking at the end result.Admin
VB6 is 14 years old, no longer supported, gets no security updates, and VB6 applications will not work on Windows 8. That, in addition to VB6 being a crappy language that encourages programmers to write dangerous and/or unmaintainable code. Like "on error resume next".
Admin
Linux is somewhat scattered on services, there being several mechanisms for running and controlling them (the rc scripts, /etc/inittab, or /etc/xinetd come to mind), plus you can roll your own like DJB has done.
Even writing the daemon itself requires nontrivial subtleties such as process group leaders and control terminals that you won't ever get right if you think that ampersand is all that's required to start a service.
I don't care for the Win32 services API much, but it's consistent, robust, and secure, and it's even remotable; assuming I have proper permissions, I can control services on remote systems. Linux pretty much requires that you grant shell access to do this remotely unless you want to roll your own service control mechanism.
Bashing Win32 for this is a WTF.
Admin
Admin
How do you figure it is conceptually the same? With a try/catch block you can determine scope and logically capture any possible errors within that section of code. Granted VB6 is old, yet I would not conceptually compare it with anything, except an old language that needs to be replaced.
Besides, you have On Error Resume Next which solves all pesky VB6 errors!
Admin
Like "nailing tits to wooden board". Apparently a German thing. I didn't care for it. Mine started leaking. I was born the wrong sex, you see...
Admin
Admin
+1
Still, it's entertaining to watch people blame a trainwreck on <insert lang here>, when trwtf is the retard behind the code.
Admin
Admin
It's the exactly same in the sense that a for loop is an assignment, a test, an increment, and a goto.
But I was more thinking in an appearance sort of way. You have a block of code that starts with {on error goto/try}, does it's normal stuff, then has {exit & label/catch}, and then some error handling. When you use try/catch, or on error goto around and entire procedure, I don't think there is a lot of difference in readabily. And you do have access to the error code and can "re-raise" it in the error handler in VB6.
I know VB6 has it's shortcomings, but it has an undeserved bad reputation that I think is 90% based on the fact that it superficially resembles something from the Commodore-64 (never mind that structually it's more like Pascal) rather than having curly-braces like the cool kids were using on their UNIX boxes.
The desire to be hip and use something based on C was a tremendous waste of time/source of errors for many, many applications written when VB6 was a current product. I think the switch to Java and C# bears this out.
There are a lot of things they have that VB6 didn't, but I maintain that the major improvement is not having to incessantly deal with memory and pointers - which is a feature that VB, and a lot of other languages, had for a long time.
I just like to call people on "VB6 is teh sux0r" and make them defend it.
Admin
Admin
Actually, VB6 apps should run on Windows 8: Support Statement for Visual Basic 6.0 on Windows Vista, Windows Server 2008, Windows 7, and Windows 8
That said, I agree that it's a good idea to convert those apps into a newer language.
Admin
The comment about the page faults is retarded. Let other people said a page fault has to do with virtual memory. When a attempt is made to access a virtual memory address and the required data is not loaded in physical memory then a page fault interrupt occurs. There is some "trap" which is an address of some code that gets executed when a page fault occurs.
It is a normal thing that happens all the time especially if the machine does not have a lot of memory. Despite fault being in the name it is not an error but just how virtual memory works.
A proper observation would be "this application uses a ton of memory" or something like that. Looking at the code it doesnt really appear to be the case.
The true WTF in this article is this comment.
Admin
Admin
Also I missed the number "50". Got to understand there are hundreds of page faults occuring every second. This number 50
On the machine I am using right now I launched firefox a few hours ago and it has had over 1.3 million page faults. Time to switch browsers I guess....
Also memory manager in windows is lazy so first time many things are access a page fault occurs. Things like memory mapped files (loading of any dll or exe into memory) will page fault like crazy until they are loaded.
Admin
This post is the WTF.
A script that does a lot of I/O was "pulled" for generating page faults?
Really? Is it the poster or the editor that apparently has no idea what a page fault is?
Admin
The real and only WTF here is the fact that this thing does not work. The fact that it's written in VB6, or isn't a true "service", or doesn't use System.Noob.MyFavoriteTimer (or whatever) as its scheduling mechanism, does not matter. If this thing would collect its garbage properly (and do whatever else it needs to do correctly- I don't have the whole code) then it would be OK. People picking out little nits like that are missing the point and, frankly, are calling their own skills (at least, in a real world sense) into question.
Services are also a WTF in their own right. The debugging experience in Visual Studio is hacked, they have to be specially installed, and so on. I would only develop a service if some kind of heavy-handed IT department requirement made me, and clearly that was not the case in this example.
Finally, this thread really points out how far this website has fallen. I tried to raise the hurricane warning... this place is turning into a bunch of semiqualified .NET proponents making fun of what amounts to .NET done slightly wrong.
Admin
So I shouldn't be using the regular windows I/O API when dealing with ini files? Here I am treating them like a regular text file input like a sucker!
Admin
Admin
Know any other way to do an error handler in VB6????
Admin
Admin
Admin
Right. Lets split the program logic up into two places, the code and the OS scheduler. That way when you've found the code, you have to searching around for the code that runs the code. Fortunately, you've put script to add the scheduler task into version control, so all you have to do is go searching around your version control database to find...
Admin
Page faults happen all the time, code asks for memory that isn't there because it's be swapped out, interrupt occurs, process suspended until the OS gets around to swapping it back in, then the offending instruction is restarted.
Now a double page fault. But that's not an app developers problem.
Admin
You stupid prick. You look it up in the documentation, don't you, pissbrain?
Admin
Funny thing: no comments here yet saying "what does that code do?" Must be because VB6 is a crappy language compared to C# or Java. Or some language more than 14 years old like ... C ... or ... Say, how old are you?
BTW, 'on error resume next' is a neccessary construct for writing scripting languages. It is the reason you can build a scripting language in BASIC, but not in PYTHON. Yes, it is dangerous to write computer programs, but somebody's got to do it.
Admin
Admin
At some point, 'services' at our place were Java programs with a GUI. One of them had a little dog, which ran about when the service was running, and sat down when the service has halted.
Cute as it was, when I had to upgrade the program, I decided to make it into a headless application.
Admin
Admin