You are here

The Daily WTF

Subscribe to The Daily WTF feed
Curious Perversions in Information Technology
Updated: 2 hours 4 min ago

Crash Diet

2 hours 37 min ago

WT Durham had never met Bruce, former sales executive and new COO of Prepackaged Pixels, before he paid a visit to WT’s department. They were responsible for maintaining the licensing API for the company’s toolkit bundle, which included their prized platform-agnostic GUI. The bundle was used for internal projects as well as for third-party licensing, and customers often bought the entire bundle just to use the GUI. Bruce wasn’t too happy about that.

“We’ve conducted several customer surveys,” Bruce said. “Two-thirds of our customer base only want the GUI toolkit, not the rest of our bundle.”

“Isn’t that a good thing?” WT replied. “We get a big markup on selling our toolkits as a bundle.”

“We could capture more of the market if we sell the GUI toolkit separately,” Bruce responded. “We need the ability to license just the GUI.”

“We’ll need to refactor our API.” WT did some mental calculations. “It’ll take our team six months.”

“All twelve of you working for six months?!” Bruce shouted. “Just to make the installer work with one toolkit? That thing is 150MB! I’ll bet the installer would be one-tenth of that size with just the GUI toolkit.” Bruce made it clear that single-toolkit licensing – and decreasing the size of the installer – would be their priorities.

Stovepipe Solution

WT wasn’t sure where Bruce, who had no programming experience, had gotten that information about the install size, but had a suspicion it was the head of the GUI toolkit team.

“He called me first.” Mindy, senior developer for the GUI toolkit, welcomed WT into her office. “Probably right after he got promoted.”

“You told him the installer size was 150MB?”

“I was making nice. Everyone complains about the size of the installer.”

WT sighed. “We inherited the installer codebase from a contractor almost ten years ago and built the licensing API on top of it. I told Bruce it would take six months to refactor for single-toolkit licensing, but who knows how long it would take to figure the base installer code out.”

“Maybe you can just trim it down?” Mindy suggested. “Fork the installer, tear out anything not related to the GUI, and stovepipe the licensing code for now. That would take less than six months, right?”

Redundant Redundancies

WT convinced the rest of his team to give the stovepipe solution a try. At worst, it would be a month wasted. At best, it would save them months of development time, allowing them to refactor the licensing code – and the underlying installer – properly later on.

While every part of the installer was audited, they would analyze their installation statistics, seeing exactly what environments they needed (and which they could chuck). If a particular environment fell below 5% of their installation base, they’d throw it out.

As the audit progressed, it became very apparent just why their installer was 150MB. Binaries were distributed in both 32- and 64-bit varieties, and each API namespace had its own binary. There were also optimized binaries for three different compilers. Each of these were duplicated again for debug and release versions. In all, 24 binaries per library were shipped in the installer.

And the installation stats? Nearly every installation was for the 64-bit GUI toolkit, using two of their three supported compilers. Out of 24 copies of each library, they needed only two.

Crash Diet

Bruce’s demeanor changed when he heard that the licensing team could deliver a GUI-only installer in a month. “I knew it wasn’t that hard!” he said, not knowing at all how hard it was.

Unfortunately, sales of the overpriced bundle – which included the GUI as well as their other toolkits – fell, as everyone bought the discounted GUI-only installer instead. Without their marked-up product sales, Prepackaged Pixels faced their first quarter without a profit. Bruce weathered the storm, but WT and others fell victim to layoffs.

Several years later, WT bought a license for Prepackaged Pixel’s toolkit bundle for a freelance project. The company no longer sold GUI-only licenses, so WT had to download the entire bundle – all 150MB of it. Prepackaged Pixels had kept their business model intact, but hadn’t been able to de-bloat their installer.

[Advertisement] Manage IT infrastructure as code across all environments with Puppet. Puppet Enterprise now offers more control and insight, with role-based access control, activity logging and all-new Puppet Apps. Start your free trial today!
Categories: Fun/Other

CodeSOD: This Hits an Association

Wed, 04/26/2017 - 12:30

I recently have needed to write some systems that do analysis on a stream of samples. The target stream of the analysis process was stored in a variable targetOfAnal, because obviously, that’s more efficient to type than targetOfAnalysis. I of course needed an analProcess and analComplete flag, and yes, my inner 13-year old was snickering the entire time.

James’s co-worker decided to demonstrate that immature dirty jokes should only be taken so far. James heard him cursing up a storm, and thus offered to help debug whatever the problem was. You could say this code is hitting the “dirty variable names” button a bit too hard. I present it here without modification, because honestly, there is no way to censor this code and have it convey its full meaning. Ready your alt-tab before the boss comes by:

for(int ishit = 0; ishit < shit.size(); ++ishit) { shitareas.clear(); shitsubareas.clear(); if(messed_up_order) { messed_up_order = false; continue; } if(shit[ishit].areas != "" || shit[ishit].subareas != "") { if(shit[ishit].areas == "" && shit[ishit].subareas != "" && ishit+1<shit.size()) { messed_up_order = true; } if(shit[ishit].areas != "") { auto shitstart = shit[ishit].areas.begin(); auto shitend = shit[ishit].areas.begin(); while(shitend != shit[ishit].areas.end()) { shitend = search(shitstart, shit[ishit].areas.end(), delim.begin(), delim.end()); string asdf(shitstart,shitend); shitareas.push_back(asdf); shitstart = shitend + delim.size(); } } if(shit[ishit].subareas != "") { auto shitstart = shit[ishit].subareas.begin(); auto shitend = shit[ishit].subareas.begin(); while(shitend != shit[ishit].subareas.end()) { shitend = search(shitstart, shit[ishit].subareas.end(), delim.begin(), delim.end()); string asdf(shitstart,shitend); shitsubareas.push_back(asdf); shitstart = shitend + delim.size(); } } if(messed_up_order) { auto shitstart = shit[ishit+1].areas.begin(); auto shitend = shit[ishit+1].areas.begin(); while(shitend != shit[ishit+1].areas.end()) { shitend = search(shitstart, shit[ishit+1].areas.end(), delim.begin(), delim.end()); string asdf(shitstart,shitend); shitareas.push_back(asdf); shitstart = shitend + delim.size(); } } } }

It’s a bit cheap to say this code is remarkably self-describing, but this is clearly a mishit. It’s crass as the dickens. If this developer was paid in cash, it wouldn’t surprise me. Imagine the code review- bet it would have been quite the pisser.

Honestly, it’s variable asdf that’s the worst thing here, but maybe that’s because I type Dvorak.

hljs.initHighlightingOnLoad(); [Advertisement] Release! is a light card game about software and the people who make it. Play with 2-5 people, or up to 10 with two copies - only $9.95 shipped!
Categories: Fun/Other

A Lost Voice

Tue, 04/25/2017 - 12:30

Having survived the scourge of Jack's automated testing debacle, Rita thought she could handle anything. Since that time, Rita had Operations burn/kill/destroy all the JCKRKS servers and set up new ones that she had full control over. Rita felt well-prepared for a future where nothing that bad could happen again. But sometimes those who only look forward are unprepared for the return of a long-forgotten relic.

In a different IVR-enabled part of their health insurance system, customers could call in to hear information about their health benefits. These benefits, as is par for anything with health insurance, were governed by a very complex set of rules, contracts, overrides, and addendums. Depending on the caller's employer, benefit administrator, subscriber level, eye color, astrological sign and feng shui positioning, their very specific set of benefit information would be read back to them.

To house this complex set of business rules, the organization depended on ILOG to keep things in order. It did the job but when it came time to tweak said rules, customers had to file a formal change request and wait weeks to see their change implemented. Customers complained about the process enough that Gregor, bringer of Jack, had the bright idea to give them a way to make rule changes on the fly themselves.

"It's quite simple, Rita," he began to explain with an arrogant tone. "It's taking too long for our customers to get their changes and it takes too much of our time to implement them. We need to create a web-based way for them to alter their business rules and I think you're just the girl to make it happen!"

"Gregor, I agree that we could do better with this, but are you sure we want our end-users messing around with complicated settings? Things could get ugly in a hurry," Rita expressed great concern.

"Point taken, but I still think this is a brilliant way to make everyone happy and more productive! Plus we can deprecate that expensive ILOG system and just store everything in a database! Get to work."

So began a large unplanned, unbudgeted project to get the web interface built with a SQL backend while exporting all the data from ILOG to a massive Excel spreadsheet. It drove Rita to her wit's end but she started to see the light at the end of the tunnel. They were now prepared for a round of beta testing by HealthLords, their biggest client (see: biggest complainer).

The HealthLords were excited to get started so they could brag about being the first insurer to set up their own business rules. They logged in to Rita's slick web interface and began to manipulate stuff. As they dug through their extensive set of rules, they came across one that was foreign to them - "PAUL TEST DO NOT DELETE". They opened it up to find the shocking description of "This is just an internal test. Those whiny HealthLord idiots will never see this once ILOG is implemented."

Almost immediately, Rita received an angry call from a big whig at HealthLords. Caught off guard, she was only able to offer a token apology and promise to look in to it. It had never been there before, so it was definitely a mystery to solve.

She dug in to the IVR platform that was still being used before and after the days of ILOG. After many rounds of tracing the code, she found the rule embedded deep in a dusty corner of the code in a class that shouldn't have processed benefit addenda at all. There stood a comment on the offending rule, "// remove this if we decides [sic] to pay for ILOG ~ Paul".

Paul hadn't been with the company for several years and had quit just before the ILOG system was implemented. But that didn't mean Rita couldn't curse his name on this day. ILOG had been covering up his test rule forever and now that it was out of the picture, it showed up again during HealthLords' beta testing. It took Gregor escalating to his bosses' bosses' boss just to keep HealthLords from backing out of their contract. [Advertisement] Universal Package Manager – store all your Maven, NuGet, Chocolatey, npm, Bower, TFS, TeamCity, Jenkins packages in one central location. Learn more today!

Categories: Fun/Other

CodeSOD: Identifying the Globally Unique

Mon, 04/24/2017 - 12:30

UUIDs, aka GUIDs are, well… unique. Unique identifiers. It’s right there in the name.

Active Directory needs to identify things. Thus, it uses GUIDs. “Omni’s” co-worker got this far, but then ran into a problem. If you print a GUID from AD, it looks like this: “35918bc9196d40ea9779889d79b753f0”, but if you print it from C#, it looks like this: “35918bc9–196d–40ea–9779–889d79b753f0”. Whatever is a programmer to do when dealing with these radically incompotible formats?

private void GetUsers(Guid guid) { byte[] bytes = guid.ToByteArray(); string native = BitConverter.ToString(bytes).Replace("-", string.Empty).ToLower(); … }

Okay, step one- turn the GUID into an array of 16 bytes. That makes sense. There’s no dashes in an array. Then we feed it into something called BitConverter. Now, I don’t know what BitConverter does, so I can only guess, and there are two likely things:

  1. It turns an array of bytes into a string
  2. It turns an array of bytes into a string AND FOR SOME REASON INSERTS DASHES

Once we’ve got the array of bytes back into a string, we can replace the dashes (which either are not there, or were inserted by BitConverter), and then convert it into lowercase, just in case hexidecimal has suddenly become case sensitive.

Of course, all of this is unnecessary. The GUID datatype in .NET overloads ToString. guid.ToString("N") would return “35918bc9196d40ea9779889d79b753f0”, just like our developer wanted.

This is at least a case of a developer not checking the documentation or lacking the instinct to ask, “Wait, does ToString have any overloads?” That, however, is not TRWTF. TRWTF is stringly typed data. GUIDs are not strings. They are numbers. We render them as strings for readability. We should not process them as strings. We should not pass them around as strings. The string representation of a GUID should not be relevant to a program.

hljs.initHighlightingOnLoad(); [Advertisement] Release! is a light card game about software and the people who make it. Play with 2-5 people, or up to 10 with two copies - only $9.95 shipped!
Categories: Fun/Other

Error'd: When Good Dev Tools Go Bad

Fri, 04/21/2017 - 12:00

"I'd say that this brings new meaning to what a 'core dump' really is," Paul N. writes.

 

"Looks like someone at Google got tired of typing exit names all day," Shawn A. writes, "And in case you wondered, voice navigation actually spelled 'ASD'."

 

"At first glance, Google News got the wrong pic, but the more you think about it, maybe it didn't," wrote Matt S.

 

Mike S. writes, "I was hoping for overflow, but all I got was NaN."

 

"I got this dialog/error message pixel for pixel (originally 2930x128) today and boy I am glad that I have two monitors or I wouldn't be able to press the OK button," writes John A.

 

"I'd love to see the datetime logic that resulted in this gem," writes Baldrick.

 

Pramod V. writes, "Now this is what I call the ULTIMATE portable!"

 

[Advertisement] Release! is a light card game about software and the people who make it. Play with 2-5 people, or up to 10 with two copies - only $9.95 shipped!
Categories: Fun/Other

CodeSOD: ByteBool

Thu, 04/20/2017 - 12:30

Tony Hoare has called null references his “billion dollar mistake”. Dealing with nulls and their consequences have created a large number of bugs, and eaten a lot of developer time. It’s certainly bad enough when you understand nulls and why they exist, but Benjamin Soddy inherited code from someone who absolutely didn’t.

First, there’s our new type, the ByteBool:

public enum ByteBool { IsFalse, IsTrue, IsNull }

Not quite FileNotFound territory. Based on this code alone, you might think that this is some legacy .NET 1.1 code, back before .NET had nullable value types, and thus there was no way to set a boolean to null.

You’d be wrong, however. Because as a sibling to ByteBool, we have the class NullHelper:

public class NullHelper { /// <summary> /// Like the Helper.GetSafeInteger but returns a negative one instead of zero which may be a valid number /// </summary> /// <param name="value">The value.</param> /// <returns></returns> public static int ConvertNullableInt(int? value) { if (value.HasValue) { return value.Value; } else { return -1; } } /// <summary> /// Like the Helper.GetSafeInteger but returns a negative one instead of zero which may be a valid number /// </summary> /// <param name="value">The value.</param> /// <returns></returns> public static int? ConvertBackToNullableInt(int value) { if (value != -1) { return (int?)value; } else { return null; } } /// <summary> /// Converts the null bool to byte bool. /// </summary> /// <param name="boolean">The boolean.</param> /// <returns></returns> public static ByteBool ConvertNullBoolToByteBool(bool? boolean) { if (boolean.HasValue) { return (boolean.Value ? ByteBool.IsTrue : ByteBool.IsFalse); } else { return ByteBool.IsNull; } } /// <summary> /// Converts the byte bool to null bool to. /// </summary> /// <param name="byteBool">The byte bool.</param> /// <returns></returns> public static bool? ConvertByteBoolToNullBoolTo(ByteBool byteBool) { switch (byteBool) { case ByteBool.IsFalse: return false; break; case ByteBool.IsTrue: return true; break; case ByteBool.IsNull: return null; break; default: return false; break; } } }

I’m no expert on the subject, but the comments alone read to me like poetry.

Like the Helper.GetSafeInteger,
but returns a negative one instead of zero which may be a valid number,
the value,
Like the Helper.GetSafeInteger,
but returns a negative one instead of zero which may be a valid number,
the value,
Converts the null bool to byte bool,
the boolean,
Converts the byte bool to null bool to,
the byte bool

Benjamin junked this code, but ByteBool is still a legend around his office. “Are you sure you aren’t ByteBooling this?” is the polite way of saying “your code is bad and you should feel bad” during code-reviews. “I found a ByteBool,” is called out when someone trawls through legacy code, in the same tone of voice as a lifeguard finding a “floater” in the pool.

hljs.initHighlightingOnLoad(); [Advertisement] Manage IT infrastructure as code across all environments with Puppet. Puppet Enterprise now offers more control and insight, with role-based access control, activity logging and all-new Puppet Apps. Start your free trial today!
Categories: Fun/Other

When Computers Fly

Wed, 04/19/2017 - 12:30

In the Before Times, the Ancients would gather in well-sheltered caverns, gather to themselves foods blessed by the gods, drink strange, unnaturally colored concoctions, and perform the Rite of the LAN Party.

In the era when the Internet was accessed by modem, to have any hope of playing a game with usable latency, you had to get all the players in the same place. This meant packing up your desktop in a car, driving to your friend’s house, and setting up your computer on whatever horizontal surface hadn’t already been claimed by another guest.



source image

In the late 90s, Shawn W was the lead support tech for a small-town ISP. He had little supervision, and lots of networking equipment at his disposal. The owners were laid back, so Shawn got to throw a LAN party every Saturday. There was a solid core group that turned out pretty much every week, but there was also a rotating cast of newbies which made great fodder for practicing your railgun snipes on “Lost Hallways”.

One weekend, one of those newbies was Derek. Derek’s main multiplayer experience was getting stoned and playing split-screen Goldeneye, in Big-Head mode. Seeing multiple computers all networked together was pretty mind-blowing for him. He ended up not gaming very much, but instead wandered around, asking questions about the setup and tripping over network cables.

“Man,” he complained, after he unplugged Shawn for the fifth time, “those shouldn’t be so easy to pull out. Like, you need a lock on it. I could make you one, I’ve got some of those industrial strength zip-ties in the car, like they could lock that cable in real tight, like they hold luggage on your car and stuff. Industrial grade, man.”

No one wanted Derek to modify their computers, and given how he had made a hobby of tripping over any cable, even ones taped to the floor, having them get yanked out was better than having their computers yanked off the folding tables. Derek was a mild nuisance, but he knew how to make up for it: he was a good sport about getting fragged, he was happy to share his stash with anybody who wanted to step behind the building, and he paid for all the pizza.

Shawn had gotten stiffed a few times, so having someone else foot the bill for all the pizza meant he was willing to forgive a lot. When Derek called him at work on Monday, Shawn was pretty well disposed to him.

“Hey, I was talking to Murphy about the party this weekend- wait, you don’t know Murph. He’s cool, man, he’s my neighbor, and we like, game a bunch? We were wondering, we’d like to set up our own network.”

Shawn was happy to help- Derek was even a customer of the ISP, so it was even technically work.

“We were thinking, like, where do you get a really long network cable?” Derek asked.

“Like, how long? Is Murphy going to be setting up in a different room of your house?”

“Nah, man, he’s gonna stay in his house. He’s my neighbor, right? We could just string a cable between our windows. Murph’s got X-Wing vs. Tie-Fighter, and it’s just like the movies. I’ve even got a cool joystick for it.”

Shawn said, “Come on by the office, and I can just give you one.” They had a few thousand foot spools of cable. Shawn made him a 100-ish foot long crossover cable, since Derek didn’t have a hub, but there were only two computers in the network.

Derek picked it up, and called back a while later, looking for some help on configuring the network. “Hey, man, I got the cable run, and like, super tied down, but um… how do we make it work? I see the green lights on the network cards.”

Shawn walked him through configuring the network, and proving it worked via a ping test. Derek was ecstatic, and started to launch into the virtues of the TIE Interceptor in death-match, when there was a sudden crash and the sound of shattering glass. Derek screamed a curse.

“Um… are you okay?” Shawn asked.

“MY COMPUTER JUST FLEW OUT THE WINDOW!” Derek cried.

“Wait… what?” Shawn tried to imagine what that might entail- he remembered Derek mentioning that it was on a folding table, maybe it had collapsed and somehow the computer had fallen out the window?

“Oh, man, look at it out there, it’s totally trashed.”

“How did your computer fly out the window?” Shawn asked.

“A car drove by and caught the network cable.”

“Wait… does Murphy live across the street?”

“Yeah, why?”

Derek’s “logic” had been that their street wasn’t very busy. He had run the cable across the street, and weighed it down with rocks, thinking that would be safe. Since that put some tension on the cable, he didn’t want it to pop out of the network card, so he had broken out those “industrial grade” zip ties, and secured the cable to his computer’s case.

“I figured it’d be fine,” Derek said glumly. “I guess I was wrong. Hey, do you know anything about building computers?”

[Advertisement] Release! is a light card game about software and the people who make it. Play with 2-5 people, or up to 10 with two copies - only $9.95 shipped!
Categories: Fun/Other

CodeSOD: The Wrong Sacrifice

Tue, 04/18/2017 - 12:30




Folks, you need to choose a different sacrificial animal for your multithreading issues. Thanks to this comment Edward found in a stubborn bit of Java code, we now know the programming gods won't take our goats.

.comment { border: none } public static boolean doSomeOSStuff() { // Forgive me father for I have sinned - with the bag of crap written in the lines below. // When running multiple threads (~500) concurrently, the damn OS commands fail at a 1% rate for no apparent reason. // There is no error message, or any indication of failure, they just don't happen and come bite you in the ass. // After much frustration, I decided to try 3 things: // 1. sacrifice a goat. - did not go as planned. // 2. semaphoring this shit. did not change anything... // 3. after each failed command, I will try and verify if it succeeded or not. If not I'll try it 4 more times. // I am now going home to take a hot shower, and cry laying on the shower floor. and /or sacrifice a few more goats. // // ... // s, . .s // ss, . .. .ss // 'SsSs, .. . .sSsS' // sSs'sSs, . . .sSs'sSs // sSs 'sSs, ... .sSs' sSs // sS, 'sSs, .sSs' .Ss // 'Ss 'sSs, .sSs' sS' // ... sSs ' .sSs' sSs ... // . sSs .sSs' .., sSs . // . .. sS, .sSs' . 'sSs, .Ss . .. // .. . 'Ss .Ss' . 'sSs. '' .. . // . . sSs ' . 'sSs, . . // ... .sS.'sSs . .. 'sSs, ... // .sSs' sS, ..... .Ss 'sSs, // .sSs' 'Ss . sS' 'sSs, // .sSs' sSs . sSs 'sSs, // .sSs'____________________________ sSs ______________'sSs, // .sSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS'.Ss SSSSSSSSSSSSSSSSSSSSSs, // ... sS' // sSs sSs // sSs sSs // sS, .Ss // 'Ss sS' // sSs sSs // sSsSs // sSs // s // snipped OS manipulation code with several cases of aforementioned ritual } hljs.initHighlightingOnLoad(); [Advertisement] High availability, Load-balanced or Basic – design your own Universal Package Manager, allow the enterprise to scale as you grow. Download and see for yourself!
Categories: Fun/Other

What Equals Equals

Mon, 04/17/2017 - 12:30

Monday morning, 10:00AM. As per usual, today's protagonist, Merv, got some coffee and settled in for his usual Monday morning routine of checking Facebook and trying to drag his brain into some semblance of gear. As he waited, the least interesting conversation ever floated to his ears from the hallway:

"It's like, yak butter, I guess? I put it in my coffee, it's supposed to do wonders."

"No way, man, I can't do dairy."

"Yeah, but it's not dairy, it's yak."

"Like, yak meat?"

"No, like, butter from yak milk."

"Then I can't have it. I'm allergic to dairy."

Merv was so stunned by the inanity of the conversation that his groggy brain didn't clue in on the obvious sign. Of course, the non-dairy drinker would be Sergey. Normally, Merv would have avoided the man this early on a Monday. He had a way of coming up with the weirdest, most bizzare problems when he debugged code, and he always ran straight to Merv to untangle them.

"Merv!" Sergey appeared, leaned into his cube. "Just the guy I was looking for. Do you have a minute?"

Begrudgingly, Merv conceded that he did, in fact, have a minute. And so, a few moments later, he found himself standing behind Sergey's chair, trying to remember what exactly this product did while Sergey explained.

"See, this data here, watch carefully while I run it—there it is. See that? It changed. I don't know why or when, but something's overwriting the data I put there. So I figured it must be here, but look, there's no assignment in this method, or this one."

"Can't you just debug through it?" asked a sleepy Merv.

"That's the weird part: it doesn't do it if I build in debug mode."

Merv frowned. "Run that by me again?"

So Sergey did. Of course, it was silly to step through a release build. There were no debugging symbols, so it was hard to tell what was going on. Merv showed him how to enable debugging symbols in a release build, but the compiler's optimizations made it hard to step through something like this. The more they dug, the weirder the behavior seemed, and the saltier the language got around the monitor.

Could it be an optimization bug in the compiler? Maybe memory values weren't being set correctly in the release build? Was it a race condition where the debugger was changing the timing? Nothing seemed right. Finally, as Merv's brain shifted into high gear, he looked over the exact lines the change was being made in.

"Here, the copy is made. I can see the value. But as we step through the next few lines, it changes, without being touched."

The code was just a simple assignment using a basic equals sign. Feeling a headache coming on, Merv tapped the equals on screen. "What exactly does that copy assignment operator do, for this class?"

They went digging. What they found was beyond the pale: macro magic changed how the function worked depending on how it was compiled. In debug mode, it was a deep copy. In release mode, it was a shallow copy; the returned object was little more than a pointer to the old one. So in release mode, changing the original (off in another thread) also changed the copy, while in debug mode, they were separate objects with their own lifetimes.

"I need more coffee," Merv muttered.

"Me too, buddy," replied Sergey.

Neither of them budged.

"Who wrote this?" demanded Merv.

The commit logs revealed the name: Patrice, who had once committed a 3000 line monstrosity all in one commit that Merv had had to rewrite from scratch. That had taken him four mugs of coffee to get through. Faced with the prospect of digging through the whole codebase to every assignment and guess if they wanted a deep or shallow copy, Merv knew the right answer: he'd have to put in a catering order with the local coffeehouse. He'd break the machine before he was done.

[Advertisement] Application Release Automation for DevOps – integrating with best of breed development tools. Free for teams with up to 5 users. Download and learn more today!
Categories: Fun/Other

Error'd: Would You Mind?

Fri, 04/14/2017 - 12:00

"Since clicking 'Yes, I mind', took me to the review page, I left a one star review," writes Pascal.

 

"As we all know, nanotechnology is huge, but don't apply nano power technology to your mind!" writes Martin

 

Conrad R. wrote, "I will not use the Secret DOM. I will not use the Secret DOM. I MUST not use the Secret DOM...or else!"

 

"Well, sorry folks, looks like the Air Force ran out of jobs," writes Scott.

 

"You can't argue with facts, because you can't argue with facts," Ben S. wrote.

 

Shahim M. wrote, "But I only have a 'Normal 2 true false null' degree, what do I do?"

 

"While trying to set my initial password for a client I'm working with, I encountered an error detailing exactly what I was trying to do in the first place," writes Alex F.

 

[Advertisement] Otter, ProGet, BuildMaster – robust, powerful, scalable, and reliable additions to your existing DevOps toolchain.
Categories: Fun/Other

All You Zombies…

Thu, 04/13/2017 - 12:30

We've all been approached for jobs where the job description was merely an endless list of buzzwords across disciplines, and there was no real way to figure out what was actually the top couple of relevant skills. The head hunter is usually of no help as they're rarely tech-savvy enough to understand what the buzzwords mean. The phone screen is often misleading as they always say that one or two skills are the important ones, and then reject candidates because they don't have expertise in some ancillary skill.

Teddy applied for a position at a firm that started out as a telco but morphed into a business service provider. The job was advertised as looking for people with at least 15-20 years of experience in designing complex systems, and Java programming. The phone screen confirmed the advert and claims of the head hunter. "This is a really great opportunity," the head hunter proclaimed.

Then it was time for the interview. The interview was the sort where you meet with the manager, a peer of the manager, and several senior members of the team, repeating your work history for each one.

There was a coding exercise to see if you could convert an int to a Roman numeral and vice versa.

Each person asked some simplistic architectural design type questions...

What is Big-O notation? How would you compare three sets of numbers to see if any number was common to all three? How would you count the number of unique words in the input and report the tally?

OK, so they have verified that you went to school and at least sort of paid attention.

Then some more complex architectural questions were added: How would you design a phone-call pricing system, and what sorts of things would you need to consider? How would you add in a new module to provide additional functionality without breaking the existing system? How would you test it all?

After several hours of this, one of the interviewers admitted that they were looking for someone who has at least 10-15 years technical experience with all of the latest technologies.

"Wait a minute, most new technologies are, by definition, new!", Teddy protested. "They haven't been around ten years?" He questioned how they expected anyone to have that many years of familiarity with anything that hasn't existed that long? Also, wasn't this supposed to be a project that required Java developers?

The interviewer nodded. "That's exactly the problem we've been facing. We simply can't find anyone who had more than a decade of experience with latest technologies." While Java was relevant, they were phasing it out in favor of the flavor of the day.

"Perhaps," Teddy suggested, "you should be looking for a candidate who has many years in the field, doing work that's the same level of complexity and kind of work as you do here." Anyone with that level of expertise should be able to pick up the new technologies as they required.

"We don't *want* to train someone," the interveiwer said, "especially a veteran. We want to hire someone with more than ten years of experience in the latest technologies. We want to build our system using the latest tools."

Teddy warned that if they did one-off projects using different technologies, it'd be fun for the developers, but it would be virtually impossible to swap people in and out as nobody would know the technology used on the next project. Perhaps it might be more prudent to pick a few mainstay technologies as their base platform and make sure that everyone is an expert in at least those skills to effect redundancy across the organization.

The interview ended shortly thereafter, and Teddy never expected to hear from them again. Several months later the same job was still posted. Teddy knew this because another head hunter approached him with the exact same job description. "This is a really great opportunity," the head hunter proclaimed.

[Advertisement] Infrastructure as Code built from the start with first-class Windows functionality and an intuitive, visual user interface. Download Otter today!
Categories: Fun/Other

CodeSOD: print_a_idiot()

Wed, 04/12/2017 - 12:30

Cédric runs the backend for a video streaming service. Since video streaming, even in modern HTML5, is still a bit of a mess, they have to be able to provide many different stream formats. So, for example, the JSON data might look like this:

{"DASH":"https:\/\/anonymised-wtfdash.akamaihd.invalid\/path\/to\/film.mpd", "HLS":"https:\/\/anonymised-wtfhls.akamaihd.invalid\/path\/to\/film.mp4\/master.m3u8", "PD":"https:\/\/anonymised-wtfpd.akamaihd.invalid\/path\/to\/film.mp4"}

They had a problem, however. Many “clever” front-end programmers, especially the ones building Flash front-ends, viewed this data not as JSON, but as a string. Thus they’d try using substring calls to pick out the specific slice of the data they needed, and then their code would break when the length of one of the URLs changed, or a new entry was added. So Cédric “fixed” this problem by randomizing the order of the keys, thus forcing them to parse the data as JSON.

Having idiot proofed his service, an advanced version of Idiot was released a few weeks later, with new features.

frame 9 { function print_a(obj, indent) { if (indent == null) { indent = ''; } var v2 = ''; for (item in obj) { if (typeof obj[item] == 'object') { v2 += indent + '[' + item + '] => Objectn'; } else { v2 += indent + '[' + item + '] => ' + obj[item] + 'n'; } v2 += print_a(obj[item], indent + ' '); } return v2; } var jsonFetcher = new LoadVars(); jsonFetcher.onLoad = function (success) { if (!success) { trace('Error connecting to server.'); } }; jsonFetcher.onData = function (thedata) { try { var v1 = JSON.parse(thedata); testvar = print_a(v1); } catch (ex) { trace(ex.name + ':' + ex.message + ':' + ex.at + ':' + ex.text); } }; jsonFetcher.load(loadVideo); } frame 17 { index = testvar.indexOf('[PD] => '); } frame 18 { index += 8; } frame 19 { index2 = testvar.indexOf('.mp4n'); } frame 20 { index2 -= index; } frame 21 { var mySubstring = new String(); mySubstring = testvar.substr(index, index2); } frame 22 { mySubstring2 = str_replace('\n', '', mySubstring); } frame 23 { mySubstring2 = mySubstring + '.mp4'; trace('mySubstring2: ' + mySubstring2); } frame 25 { Videoplayer.contentPath = mySubstring2; Videoplayer.volume = _root.VideoVolume; }

The function print_a is… special. Given an object, its job is to format it as a pretty string, complete with line-breaks. The goal, obviously, is to allow them to use string slicing to pick out the specific fields they care about (instead of just accessing them directly), but along the way, the line breaks in their print_a function went from being “\n” to just “n”. Notice how they attempt to strip the “\n”s in frame 22. Similarly, through frame 19 to 21, they attempt to trim the “.mp4n” off the end (which they just put there), so that in frame 23, they can just pop back on a “.mp4”.

All of this, amazingly, worked. Unfortunately, you can see that the request was sent on frame 9. The results of the request were checked on frame 17. Since this is video, we can assume a frame-rate of 29.97 frames per second, which means that if the request isn’t serviced in about a quarter of a second, testvar isn’t going to have any data, and everything after it is going to fail, so by frame 25, there’s no video URL to load.

Of course, to start this process, they use JSON.parse, making 90% of this code utterly redundant.

hljs.initHighlightingOnLoad(); [Advertisement] BuildMaster integrates with an ever-growing list of tools to automate and facilitate everything from continuous integration to database change scripts to production deployments. Interested? Learn more about BuildMaster!
Categories: Fun/Other

My Machine Is Full

Tue, 04/11/2017 - 12:30

In the mid-90s, Darren landed his first corporate job at a company that sold IT systems to insurance brokers. Their software ran on servers about the size of small chest freezers—outdated by the 70s, let alone the 90s. Every month, they'd push out software fixes by sending each customer between 3 and 15 numbered floppy disks. The customers would have to insert the first disk, type UPDATE into the console, and wait for "Insert Disk Number X" prompts to appear on screen.

It wasn't slick, but it worked. The firm even offered a recycling service for the hundreds of disks that eventually built up at customer sites.

While working there, Darren became unfortunately well acquainted with one particular insurance broker, Mr. Lasco. The man refused all offers of training ("Too expensive!") and paid support ("You don't know enough!"), and was too good to read instructions, but could always be counted on to tie up some poor tech support rep's phone every time a new update went out. He never paid a penny or even thanked anybody for the help. When told about it, management just shrugged their shoulders. Mr. Lasco's firm did have a big contract with them, after all.

Early one Monday morning, Darren answered his phone, only to receive an ear-splitting tirade. As Mr. Lasco ranted, Darren held in a sigh and used the time to start filing a support ticket.

"What's the nature of your problem, sir?" he asked during the gap in which Mr. Lasco paused to breathe.

"I—it's—your damn update won't work! Again!" Mr. Lasco sputtered. "My machine is full!"

Darren frowned. That wasn't an error message that the update process would ever throw. "'Full?' Hmm, maybe one of the server's hard drives is out of disk space? Maybe you need to—"

"No, you fool, it's full! It's FULL!" Mr. Lasco snapped. "I KNEW this would happen eventually! Do you know how much money I'm losing right now with this thing down? I want one of your people to come out here and fix this immediately!"

The demand prompted an eyeroll from Darren, who already knew Mr. Lasco would never pay for a consultant's time. Still, this was a perfect way to get him off the phone. "Why don't I forward you to your sales rep?"

To Darren's amazement—and pity—a software engineer was dispatched within the hour to drive several hundred miles to Mr. Lasco's site, with instructions to call Darren with updates.

By late afternoon, the call came. The engineer was laughing so hard, he couldn't talk.

"Is everything OK?" prompted Darren.

"Wait'll you hear this." The engineer struggled to breathe. "There's a gap in the server casing. All this time, Lasco's been inserting update disks into the server, and couldn't force any more in. I popped the case open, and swear to God, there must be a few hundred disks crammed in there, easy. Years of updates!"

Darren joined in the mirth, but it was short-lived. The poor engineer had to spend 7 hours onsite carefully extracting floppy disks wedged between drives and memory cards, sorting them, then applying the updates in order.

The one silver lining to the whole affair was that Mr. Lasco never called them again.

[Advertisement] Manage IT infrastructure as code across all environments with Puppet. Puppet Enterprise now offers more control and insight, with role-based access control, activity logging and all-new Puppet Apps. Start your free trial today!
Categories: Fun/Other

CodeSOD: A Piece of the Variable

Mon, 04/10/2017 - 12:30

In the Star Trek episode, “A Piece of the Action”, Kirk and his crew travel to Sigma Iotia II, a planet last visited before the Prime Directive of non-interference existed. Well, they left behind a book, Chicago Mobs of the Twenties, which the Iotians took as a holy guide, to be imitated and followed even if they didn’t quite understand it, a sort of sci-fi cargo-cult. Cue the crew of the Enterprise being threatened with Tommy Guns and guys doing bad Al Capone impressions.

Michael’s co-worker may have fallen into a similar trap. An advanced developer came to him, and gave him a rule: in PHP, since variables may be used without being declared, it’s entirely possible to have an unset variable. Thus, it’s a good practice to check and see if the variable is set before you use it. Normally, we use this to check if, for example, the submitted form contains certain fields.

Like Bela Okmyx, the “Boss” of Sigma Iotia II, this developer may have read the rules, but they certainly didn’t understand them.

$numDIDSthisMonth=0; if(isset($numDIDSthisMonth)) { if($numDIDSthisMonth == "") { $numDIDSthisMonth=0; } } $numTFDIDSthisMonth=0; if(isset($numTFDIDSthisMonth)) { if($numTFDIDSthisMonth == "") { $numTFDIDSthisMonth=0; } } /* $numDIDSthisMonthToCharge=$_POST['numDIDSthisMonthToCharge']; if(isset($numDIDSthisMonthToCharge)){ if($numDIDSthisMonthToCharge == ""){ $numDIDSthisMonthToCharge=0; } } */ $STDNPthisMonth=0; if(isset($STDNPthisMonth)) { if($STDNPthisMonth == "") { $STDNPthisMonth=0; } } $TFNPthisMonth=0; if(isset($TFNPthisMonth)) { if($TFNPthisMonth == "") { $TFNPthisMonth=0; } } $E911thisMonth=0; if(isset($E911thisMonth)) { if($E911thisMonth == "") { $E911thisMonth=0; } } $E411thisMonth=0; if(isset($E411thisMonth)) { if($E411thisMonth == "") { $E411thisMonth=0; } } /* $PBthisMonth=0; if(isset($PBthisMonth)) { if($PBthisMonth == "") { $PBthisMonth=0; } } */ $TFthisMonth=0; if(isset($TFthisMonth)) { if($TFthisMonth == "") { $TFthisMonth=0; } }

As you can see, in this entire block of variables, we first set the variable, then we check, if the variable isset, on the off-chance it magically got unset between lines of code, and then we double check to see if it’s an empty string, and if it is, make it zero.

For extra credit, some of these variables are used in the application. Most of them are not actually used anywhere. See if you can guess each ones!

hljs.initHighlightingOnLoad(); [Advertisement] Manage IT infrastructure as code across all environments with Puppet. Puppet Enterprise now offers more control and insight, with role-based access control, activity logging and all-new Puppet Apps. Start your free trial today!
Categories: Fun/Other

Error'd: Our Deepest Regrets (and 20% off your next purchase)

Fri, 04/07/2017 - 12:00

"I too have always felt that discount codes are a great way to express sympathy," writes Shawn A.

 

Peter wrote, "Those folks over at Amazon UK sure have an interesting concept of gardening tools."

 

"I tried to unsubscribe from a Washington Post newsletter, but I can't seem to uncheck the box," wrote Peter C.

 

"I, for one, love the idea of having my CPU wall-mounted," writes Daniel.

 

"My trial ends in 90 years you say? I think I'll 'Buy Later' instead," wrote Mike S.

 

Nikolaus R. writes, "Yes, Google Maps, I really got it."

 

"Ummm...so how does closing my PC help me avoid having to restart my PC?" wrote Daniel.

 

[Advertisement] Release! is a light card game about software and the people who make it. Play with 2-5 people, or up to 10 with two copies - only $9.95 shipped!
Categories: Fun/Other

CodeSOD: An Extinction Event

Thu, 04/06/2017 - 12:30

Microsoft’s C# has become an extremely popular language for “enterprise” development, and it’s sobering to think that: yes, this language has been around for 15 years at this point. That’s long enough for the language to have grown from a “sort of Java with reliability, productivity and security deleted.” (James Gosling, one of the creators of Java) to “sort of Java, but with generics and lambdas actually implemented in a useful way, and not completely broken by design”.

15 years is also more than enough time for a project to grow out of control, turning into a sprawling mass of tentacles with mouths on the ends, thrashing about looking for a programmer’s brain to absorb. Viginia N is currently locked in a struggle for sanity against one such project.

Some of the code looks like this:

if (m_ProgEnt!=null) { if (m_ProgEnt.SAFF_SIG==m_PSOC_SIG) { ChangePosition("P",true,(bool)ar[6],(DateTime)ar[1],(DateTime)ar[5]); } else { ChangePosition("P",true,(bool)ar[6], (DateTime)ar[1], (DateTime)ar[5]); } } else { } ChangePosition("P",true,(bool)ar[6],(DateTime)ar[1],(DateTime)ar[5]);

You’ll note that all three calls to ChangePosition do exactly the same thing. I also don’t know what the array ar holds, but apparently it’s a mixture of booleans and date-time objects.

The code-base is littered with little meaningless conditionals, which makes the meaningful ones so much more dangerous:

if ( demandesDataRowView["SGESDEM_SOC"].ToString().Equals(demandesDataRowView["SGESDEM_SIG"].ToString()) && demandesDataRowView["SGESDEM_SIG"].ToString().Length > 0 ) sSocieteCour = demandesDataRowView["SGESDEM_SIG"].ToString(); else sSocieteCour = demandesDataRowView["SGESDEM_SOC"].ToString();

In another part of the code, they define a ResultsetFields object twice, storing it in the same variable, and never using the first definition for anything:

int iFieldIndex = 0; ResultsetFields fields = new ResultsetFields(19); //DemandesDetail fields fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_REFLIVR, iFieldIndex++, "SGESDEMD_REFLIVR"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_SOCLIVR, iFieldIndex++, "SGESDEMD_SOCLIVR"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_QTEAUT, iFieldIndex++, "SGESDEMD_QTEAUT"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_PU, iFieldIndex++, "SGESDEMD_PU"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_TYPE, iFieldIndex++, "SGESDEMD_TYPE"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_REMCLIENT, iFieldIndex++, "SGESDEMD_REMCLIENT"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_QTEASORT, iFieldIndex++, "SGESDEMD_QTEASORT"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_LBID, iFieldIndex++, "SGESDEMD_LBID"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_LIVRPAR, iFieldIndex++, "SGESDEMD_LIVRPAR"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_CMDNUM, iFieldIndex++, "SGESDEMD_ASORT"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_REFDEM, iFieldIndex++, "SGESDEMD_REFDEM"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_SOCDEM, iFieldIndex++, "SGESDEMD_SOCDEM"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_QTESOR, iFieldIndex++, "SGESDEMD_QTESOR"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_QTERECENT, iFieldIndex++, "SGESDEMD_QTERECENT"); // Stock fields fields.DefineField(STOCKFieldIndex.SREF_SOC , iFieldIndex++, "SREF_SOC"); fields.DefineField(STOCKFieldIndex.SREF_COD , iFieldIndex++, "SREF_COD"); fields.DefineField(STOCKFieldIndex.SREF_NSTOCK , iFieldIndex++, "SREF_NSTOCK"); fields.DefineField(STOCKFieldIndex.SREF_QTERES , iFieldIndex++, "SREF_QTERES"); fields.DefineField(STOCKFieldIndex.SREF_QTEASORT , iFieldIndex++, "SREF_QTEASORT"); //SNIP [... 1500 lines without using fields] iFieldIndex = 0; fields = new ResultsetFields(29); //DemandesDetail fields fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_REFLIVR, iFieldIndex++, "SGESDEMD_REFLIVR"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_SOCLIVR, iFieldIndex++, "SGESDEMD_SOCLIVR"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_QTEAUT, iFieldIndex++, "SGESDEMD_QTEAUT"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_QTELIVR, iFieldIndex++, "SGESDEMD_QTELIVR"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_PU, iFieldIndex++, "SGESDEMD_PU"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_TYPE, iFieldIndex++, "SGESDEMD_TYPE"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_REMCLIENT, iFieldIndex++, "SGESDEMD_REMCLIENT"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_QTEASORT, iFieldIndex++, "SGESDEMD_QTEASORT"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_LBID, iFieldIndex++, "SGESDEMD_LBID"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_LIVRPAR, iFieldIndex++, "SGESDEMD_LIVRPAR"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_CMDNUM, iFieldIndex++, "SGESDEMD_ASORT"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_REFDEM, iFieldIndex++, "SGESDEMD_REFDEM"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_SOCDEM, iFieldIndex++, "SGESDEMD_SOCDEM"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_DOAA_ID, iFieldIndex++, "SGESDEMD_DOAA_ID"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_DOALID, iFieldIndex++, "SGESDEMD_DOALID"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_DOAA_ANNEE, iFieldIndex++, "SGESDEMD_DOAA_ANNEE"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_VALMASSE, iFieldIndex++, "SGESDEMD_VALMASSE"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_QTERECENT, iFieldIndex++, "SGESDEMD_QTERECENT"); fields.DefineField(DEMANDESDETAILFieldIndex.SGESDEMD_QTESOR, iFieldIndex++, "SGESDEMD_QTESOR"); // Stock fields fields.DefineField(STOCKFieldIndex.SREF_SOC , iFieldIndex++, "SREF_SOC"); fields.DefineField(STOCKFieldIndex.SREF_COD , iFieldIndex++, "SREF_COD"); fields.DefineField(STOCKFieldIndex.SREF_DES , iFieldIndex++, "SREF_DES"); fields.DefineField(STOCKFieldIndex.SREF_NSTOCK , iFieldIndex++, "SREF_NSTOCK"); fields.DefineField(STOCKFieldIndex.SREF_QTERES , iFieldIndex++, "SREF_QTERES"); fields.DefineField(STOCKFieldIndex.SREF_QTEASORT , iFieldIndex++, "SREF_QTEASORT"); fields.DefineField(STOCKFieldIndex.SREF_BIEN , iFieldIndex++, "SREF_BIEN"); fields.DefineField(STOCKPARAMFieldIndex.SREFP_LOT , iFieldIndex++, "SREFP_LOT"); fields.DefineField(STOCKPARAMFieldIndex.SREFP_KIT , iFieldIndex++, "SREFP_KIT"); fields.DefineField(STOCKPARAMFieldIndex.SREFP_EPI , iFieldIndex++, "SREFP_EPI");

These three different samples I’ve used here did not come from various methods throughout the code-base. No, to the contrary, these are all in the same method, lnkPrCompte_LinkClicked. That would be an event-handling method. One event handling method. In a .NET solution which contains over 70 individual DLL and executable projects, with hundreds of classes per DLL, and a whopping 65 million lines of code- roughly one line for each year the dinosaurs have been extinct.

Virginia is trying valiantly to refactor the project into something supportable. She’s tried to bring in tools like ReSharper to speed the effort along, but ReSharper takes one look at the code base, decides the dinosaurs had the right idea, and promptly dies.

hljs.initHighlightingOnLoad(); [Advertisement] Manage IT infrastructure as code across all environments with Puppet. Puppet Enterprise now offers more control and insight, with role-based access control, activity logging and all-new Puppet Apps. Start your free trial today!
Categories: Fun/Other

By the Book

Wed, 04/05/2017 - 12:30

A long, long time ago when C was all the rage and C++ was just coming into its own, many people that were running applications on Unix boxes used the X-Windowing system created by MIT to build their GUI applications. This was the GUI equivalent of programming in assembly; it worked, but was cumbersome and hard to do. Shortly thereafter, the Xt-Intrinsics library was created as a wrapper, which provided higher level entities that were easier to work with. Shortly after that, several higher level toolkits that were even easier to use were created. Among these was Motif, created by DEC, HP, etc.

While these higher level libraries were easier to use than raw X-lib, they were not without their problems.

Sam was a senior developer at Military Widgets, Inc. His responsibilities included the usual architectural/development duties on his project. One day, Pat, Sam's boss, asked him to stay late. "Taylor has a bug that he just can't crack," Pat explained. "I want someone with a little more experience to give him a hand."

It seems that after making some changes to their Motif GUI, the application started throwing stack dumps on every transaction. As a result, every transaction was rolling back as failed. Taylor insisted that his code was correct and that it was not the cause of the problem. To this end, Pat asked Sam to stay late one afternoon and take a look at it.

After some company-sponsored pizza, Pat had Taylor hand Sam a stack trace. In the middle of it was a call to:

XmTextSetString(theWidget,"String to display");

Sam laughed. "Taylor," he said, "this macro has a known memory leak." Since the macro was just a wrapper, Taylor should just replace it with the corresponding underlying call to do the actual work:

XmTextReplace(theWidget, (XmTextPosition) 0, XmTextGetLastPosition(theWidget), "String to display");

This was long before Tim Berners-Lee created the internet on top of DARPA-net, so all they had to go on was a very thick set of printed manuals. Taylor pulled out the Motif manual and showed Sam the proper use of the XmTextSetString macro. "I followed the procedures laid out in the manual."

"Just because it's in the manual, doesn't mean it's *right*," Sam said. "The Motif code has a bug in it. That does happen, you know."

Taylor insisted the problem must be someplace else. "I followed the instructions in the manual!" Sam looked at Pat, raised an eyebrow and sighed.

Pat asked Taylor to try the change. Taylor refused, insisting that he did it right and that Sam didn't know what he was talking about.

Sam said he was going to his desk and would have it temporarily patched in 5 minutes.

He opened a file called last.h, and undefined the XmTextSetString macro and then redefined it using his fix. Then he kicked off a 3.5 hour full build, opened another window and typed the command to run the server, but did not enter it.

Sam returned to the conference room, explained what he did and told Taylor to keep moving the mouse to keep Sam's box from closing. Then in 3.5 hours, he could hit ENTER and test the result.

He told Pat that there might be other problems that they could encounter at other points in the application, but this WAS the cause of this problem, and that he'd see that in several hours. He also pointed out that this was only a hack, that it should NOT be checked in, and that all of the actual macro uses should be replaced with the correct code. Then he went home, relegating Taylor to several hours of jiggling a mouse, all the while mumbling that this wouldn't work because he had done it right.

When the build finished, Pat watched as Taylor launched the server, and brought the GUI to the last keystroke before the error had been occurring. To Taylor's surprise, the transaction went through without the exception. Pat then had him jam a whole year of transactions down that pipe via their batch mechanism. It took all night but it worked.

The next day, Pat had Taylor manually tracking down and replacing every instance of that macro with the corrected code, because doing what the manual says without verifying that it's right is NOT doing it right.

[Advertisement] Onsite, remote, bare-metal or cloud – create, configure and orchestrate 1,000s of servers, all from the same dashboard while continually monitoring for drift and allowing for instantaneous remediation. Download Otter today!
Categories: Fun/Other

Coded Smorgasbord: Cerebral Flatulence

Tue, 04/04/2017 - 12:30

There’s plenty of bad code that makes you ask, “what were they thinking?” There’s a whole bunch of code we get, however, that doesn’t even raise that question- the programmer responsible simply wasn’t thinking. Today, let’s examine a few “programmer brain-farts”. We turn our attention first, to Jim C.

While reviewing some unit tests, he found this line:

if (!succeeded) { SmartAssert::IsTrue(succeeded, messageStr); }

This, obviously, confirms that succeeded is false, and the asserts that succeeded shouldn’t be false. Perhaps not so smart an assert. Jim ran blame to find the party responsible, but as it turned out- he had written this code six months earlier.

Oh, to live in a world where we are the only source of our own pain. Jason is not so lucky. It was the eve of a major release, and there was a bug. Certain date values were being miscalculated. What could possibly be the cause?

Well, after a frantic investigation, he found a fellow developer had done this:

SystemTime startTime = getCurrentSystemTime().subtractSeconds(TimeUnit.HOURS.toMillis(1));

What is supposed to be calculating out one hour prior was actually calculating out 1000 times that much. While they discovered this bug right before a release, the code had been in production for months.

Meanwhile, Dave was hunting through some code, trying to understand some of the output. Eventually, he traced the problem to a function called generateUUID.

public static String generateGUID(AuditLog auditLog) { String guid = UUID.randomUUID().toString(); return (guid + auditLog.getContextName() + auditLog.getRequestStart().getTime()); }

This was simply a case of a very poorly named function. At no point in its history had it ever actually generated a UUID, and had always returned some variation on this string concatenated version.

hljs.initHighlightingOnLoad(); [Advertisement] Release! is a light card game about software and the people who make it. Play with 2-5 people, or up to 10 with two copies - only $9.95 shipped!
Categories: Fun/Other

Radio WTF: Space for Guests

Mon, 04/03/2017 - 12:30
Radio WTF Presents! Jump to transcript (coming soon)

Welcome back to Radio WTF. Last time, Captain Garneau saved the station, yet again, from a mysterious threat. This week, her skills will be put to the maximum test, when the Director visits…

Soundcloud Links: Radio WTF: Space for Guests

Direct Download: SpaceForGuests.mp3

Starring (in order of appearance) Jane Bailey... as Commander Josephine Garneau
Alex Papadimoulis... as Director Royce Clifton, and Pascal Langois
Lorne Kates... as Marius Langois
Heather Houghton... as E.L.L.A.
Remy Porter... as luggage guest, and THE Gus Dowler
Patrick Roach... as Dr. Taseer
Devin Sweeny... as Roberta Bondar pilot
and Mark Bowytz as the scream in space no one can hear

Featuring the voice of Paul Rousse of VoiceByPaul.com, and the song "Slow Burn" by Kevin MacLeod of Incompetech.com.

Transcript (coming soon) [Advertisement] Manage IT infrastructure as code across all environments with Puppet. Puppet Enterprise now offers more control and insight, with role-based access control, activity logging and all-new Puppet Apps. Start your free trial today!
Categories: Fun/Other

Error'd: Oh JavaScript!

Fri, 03/31/2017 - 12:00

"I have a feeling that VS Code is trying to tell me that the object class provides functionality common to all JavaScript objects," writes Eric.

 

"Hmmm...When I set out to upgrade my broadband speed, 'null' wasn't quite what I had in mind," writes Michael R.

 

"All I wanted to know was how far sound travels in 15 milliseconds," Andreas wrote, "I didn't realize that I would need to take the wheelbase of a Mitsubishi Galant into account."

 

Martin wrote, "I think they must be targeting a younger demographic who will be around for the 2083 issue."

 

"Do you want a Skynet apocalypse? Because this how you get a Skynet apocalypse," Jeff H. wrote.

 

"Seems my VPN provider knows when to cancel my lifetime subscription in advance. Do they know something that I don't?" writes Niels.

 

Pascal wrote, "This message doesn't not confuse me greatly."

 

[Advertisement] Scale your release pipelines, creating secure, reliable, reusable deployments with one click. Download and learn more today!
Categories: Fun/Other

Pages

Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer