Dilbert





The Daily WTF

Error'd: Be Patient!...OK?;

"I used to feel nervous when making payments online, but now I feel ...um...'Close' about it," writes Jeff K.

 

"Looks like me and Microsoft have different ideas of what 75% means," Gary S. wrote.

 

George writes, "Try this one at home! Head to tdbank.com, search for 'documents for opening account' and enjoy 8 solid pages of ...this."

 

"I'm confused if the developers knew the difference between Javascript and Java. This has to be a troll...right?" wrote JM.

 

Tom S. writes, "Saw this in the Friendo app, but what I didn't spot was an Ok button. "

 

"I look at this and wonder if someone could deny a vacation requests because of a conflict of 0.000014 days with another member of staff," writes Rob.

 

[Advertisement] Forget logs. Next time you're struggling to replicate error, crash and performance issues in your apps - Think Raygun! Installs in minutes. Learn more.


Wait Low Down;

As mentioned previously I’ve been doing a bit of coding for microcontrollers lately. Coming from the world of desktop and web programming, it’s downright revelatory. With no other code running, and no operating system, I can use every cycle on a 16MHz chip, which suddenly seems blazing fast. You might have to worry about hardware interrupts- in fact I had to swap serial connection libraries out because the one we were using misused interrupts and threw of the timing of my process.

And boy, timing is amazing when you’re the only thing running on the CPU. I was controlling some LEDs and if I just went in a smooth ramp from one brightness level to the other, the output would be ugly steps instead of a smooth fade. I had to use a technique called temporal dithering, which is a fancy way of saying “flicker really quickly” and in this case depended on accurate, sub-microsecond timing. This is all new to me.

Speaking of sub-microsecond timing, or "subus", let's check out Jindra S’s submission. This code also runs on a microcontroller, and for… “performance” or “clock accuracy” is assembly inlined into C.

/*********************** FUNCTION v_Angie_WaitSubus *******************************//**
@brief Busy waits for a defined number of cycles.
The number of needed sys clk cycles depends on the number of flash wait states,
but due to the caching, the flash wait states are not relevant for STM32F4.
4 cycles per u32_Cnt
*******************************************************************************/
__asm void  v_Angie_WaitSubus( uint32_t u32_Cnt )
{
loop
    subs r0, #1
    cbz  r0, loop_exit
    b loop
loop_exit
    bx lr
}

Now, this assembly isn’t the most readable thing, but the equivalent C code is pretty easy to follow: while(--u32_Cnt); In other words, this is your typical busy-loop. Since this code is the only code running on the chip, no problem right? Well, check out this one:

/*********************** FUNCTION v_Angie_IRQWaitSubus *******************************//**
@brief Busy waits for a defined number of cycles.
The number of needed sys clk cycles depends on the number of flash wait states,
but due to the caching, the flash wait states are not relevant for STM32F4.
4 cycles per u32_Cnt
*******************************************************************************/
__asm void  v_Angie_IRQWaitSubus( uint32_t u32_Cnt )
{
IRQloop
    subs r0, #1
    cbz  r0, IRQloop_exit
    b IRQloop
IRQloop_exit
    bx lr
}

What do you know, it’s the same exact code, but called IRQWaitSubus, implying it’s meant to be called inside of an interrupt handler. The details can get fiendishly complicated, but for those who aren’t looking at low-level code on the regular, interrupts are the low-level cousin of event handlers. It allows a piece of hardware (or software, in multiprocessing systems) to notify the CPU that something interesting has happened, and the CPU can then execute some of your code to react to it. Like any other event handler, interrupt handlers should be fast, so they can update the program state and then allow normal execution to continue.

What you emphatically do not do is wait inside of an interrupt handler. That’s bad. Not a full-on WTF, but… bad.

There’s at least three more variations of this function, with slightly different names, scattered across different modules, all of which represent a simple busy loop.

Ugly, sure, but where’s the WTF? Well, among other things, this board needed to output precisely timed signals, like say, a 500Hz square wave with a 20% duty cycle. The on-board CPU clock was a simple oscillator which would drift- over time, with changes in temperature, etc. Also, interrupts could claim CPU cycles, throwing off the waits. So Jindra’s company had placed this code onto some STM32F4 ARM microcontrollers, shipped it into the field, and discovered that outside of their climate controlled offices, stuff started to fail.

The code fix was simple- the STM32-series of processors had a hardware timer which could provide precise timing. Switching to that approach not only made the system more accurate- it also meant that Jindra could throw away hundreds of lines of code which was complicated, buggy, and littered with inline assembly for no particular reason. There was just one problem: the devices with the bad software were already in the field. Angry customers were already upset over how unreliable the system was. And short of going on site to reflash the microcontrollers or shipping fresh replacements, the company was left with only one recourse:

They announced Rev 2 of their product, which offered higher rates of reliability and better performance, and only cost 2% more!

[Advertisement] Forget logs. Next time you're struggling to replicate error, crash and performance issues in your apps - Think Raygun! Installs in minutes. Learn more.


The Wizard Algorithm;

Password requirements can be complicated. Some minimum and maximum number of characters, alpha and numeric characters, special characters, upper and lower case, change frequency, uniqueness over the last n passwords and different rules for different systems. It's enough to make you revert to a PostIt in your desk drawer to keep track of it all. Some companies have brillant employees who feel that they can do better, and so they create a way to figure out the password for any given computer - so you need to neither remember nor even know it.

Kendall Mfg. Co. (estab. 1827) (3092720143)

History does not show who created the wizard algorithm, or when, or what they were smoking at the time.

Barry W. has the misfortune of being a Windows administrator at a company that believes in coming up with their own unique way of doing things, because they can make it better than the way that everyone else is doing it. It's a small organization, in a sleepy part of a small country. And yet, the IT department prides itself on its highly secure practices.

Take the password of the local administrator account, for instance. It's the Windows equivalent of root, so you'd better use a long and complex password. The IT team won't use software to automate and keep track of passwords, so to make things extremely secure, there's a different password for every server.

Here's where the wizard algorithm comes in.

To determine the password, all you need is the server's hostname and its IP address.

For example, take the server PRD-APP2-SERV4 which has the IP address 178.8.1.44.

Convert the hostname to upper case and discard any hyphens, yielding PRDAPP2SERV4.

Take the middle two octets of the IP address. If either is a single digit, pad it out to double digits. So 178.8.1.44 becomes 178.80.10.44 which yields 8010. Now take the last character of the host name; if that's a digit, discard it and take the last letter, otherwise just take the last letter, which gives us V. Now take the second and third letters of the hostname and concatenate them to the 8010 and then stick that V on the end. This gives us 8010RDV. Now take the fourth and fifth letters, and add them to the end, which makes 8010RDVAP. And there's your password! Easy.

It had been that way for as long as anyone could remember, until the day someone decided to enable password complexity on the domain. From then on, you had to do all of the above, and then add @!#%&$?@! to the end of the password. How would you know whether a server has a password using the old method or the new one? Why by a spreadsheet available on the firm-wide-accessible file system, of course! Oh, by the way, there is no server management software.

Critics might say the wizard algorithm has certain disadvantages. The fact that two people, given the same hostname and IP address, often come up with different results for the algorithm. Apparently, writing a script to figure it out for you never dawned on anyone.

Or the fact that when a server has lost contact with the domain and you're trying to log on locally and the phone's ringing and everyone's pressuring you to get it resolved, the last thing you want to be doing is math puzzles.

But at least it's better than the standard way people normally do it!

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!


CodeSOD: A Unique Specification;

One of the skills I think programmers should develop is not directly programming related: you should be comfortable reading RFCs. If, for example, you want to know what actually constitutes an email address, you may want to brush up on your BNF grammars. Reading and understanding an RFC is its own skill, and while I wouldn’t suggest getting in the habit of reading RFCs for fun, it’s something you should do from time to time.

To build the skill, I recommend picking a simple one, like UUIDs. There’s a lot of information encoded in a UUID, and five different ways to define UUIDs- though usually we use type 1 (timestamp-based) and type 4 (random). Even if you haven’t gone through and read the spec, you already know the most important fact about UUIDs: they’re unique. They’re universally unique in fact, and you can use them as identifiers. You shouldn’t have a collision happen within the lifetime of the universe, unless someone does something incredibly wrong.

Dexen encountered a database full of collisions on UUIDs. Duplicates were scattered all over the place. Since we’re not well past the heat-death of the universe, the obvious answer is that someone did something entirely wrong.

use Ramsey\Uuid\Uuid;
 
$model->uuid = Uuid::uuid5(Uuid::NAMESPACE_DNS, sprintf('%s.%s.%s.%s', 
    rand(0, time()), time(), 
    static::class, config('modelutils.namespace')))->toString();

This block of PHP code uses the type–5 UUID, which allows you to generate the UUID based on a name. Given a namespace, usually a domain name, it runs it through SHA–1 to generate the required bytes, allowing you to create specific UUIDs as needed. In this case, Dexen’s predecessor was generating a “domain name”-ish string by combining: a random number from 0 to seconds after the epoch, the number of seconds after the epoch, the name of the class, and a config key. So this developer wasn’t creating UUIDs with a specific, predictable input (the point of UUID–5), but was mixing a little from the UUID–1 time-based generation, and the UUID–4 random-based generation, but without the cryptographically secure source of randomness.

Thus, collisions. Since these UUIDs didn’t need to be sortable (no need for UUID–1), Dexen changed the generation to UUID–4.

[Advertisement] ProGet supports your applications, Docker containers, and third-party packages, allowing you to enforce quality standards across all components. Download and see how!


CodeSOD: The Sanity Check;

I've been automating deployments at work, and for Reasons™, this is happening entirely in BASH. Those Reasons™ are that the client wants to use Salt, but doesn't want to give us access to their Salt environment. Some of our deployment targets are microcontrollers, so Salt isn't even an option.

While I know the shell well enough, I'm getting comfortable with more complicated scripts than I usually write, along with tools like xargs which may be the second best shell command ever invented. yes is the best, obviously.

The key point is that the shell, coupled with the so-called "Unix Philosophy" is an incredibly powerful tool. Even if you already know that it's powerful, it's even more powerful than you think it is.

How powerful? Well, how about ripping apart the fundamental rules of mathematics? An anonymous submitter found this prelude at the start of every shell script in their organization.

#/usr/bin/env bash declare -r ZERO=$(true; echo ${?}) declare -r DIGITZERO=0 function sanity_check() { function err_msg() { echo -e "\033[31m[ERR]:\033[0m ${@}" } if [ ${ZERO} -ne ${DIGITZERO} ]; then err_msg "The laws of physics doesn't apply to this server." err_msg "Real value ${ZERO} is not equal to ${DIGITZERO}." exit 1 fi } sanity_check

true, like yes, is one of those absurdly simple tools: it's a program that completes successfully (returning a 0 exit status back to the shell). The ${?} expression contains the last exit status. Thus, the variable $ZERO will contain… 0. Which should then be equal to 0.

Now, maybe BASH isn't BASH anymore. Maybe true has been patched to fail. Maybe, maybe, maybe, but honestly, I'm wondering whose sanity is actually being checked in the sanity_check?

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!


Error'd: Just Handle It;

Clint writes, "On Facebook, I tried to report a post as spam. I think I might just have to accept it."

 

"Jira seems to have strange ideas about my keyboard layout... Or is there a key that I don't know about?" writes Rob H.

 

George wrote, "There was deep wisdom bestowed upon weary travelers by the New York subway system at the Jamaica Center station this morning."

 

"Every single number field on the checkout page, including phone and credit card, was an integer. Just in case, you know, you felt like clicking a lot," Jeremiah C. writes.

 

"I don't know which is more ridiculous: that a Linux recovery image is a Windows 10, or that there's a difference between Pro and Professional," wrote Dima R.

 

"I got my weekly workout summary and, well, it looks I might have been hitting the gym a little too hard," Colin writes.

 

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!


The New Guy (Part II): Database Boogaloo;

When we last left our hero Jesse, he was wading through a quagmire of undocumented bad systems while trying to solve an FTP issue. Several months later, Jesse had things figured out a little better and was starting to feel comfortable in his "System Admin" role. He helped the company join the rest of the world by dumping Windows NT 4.0 and XP. The users whose DNS settings he bungled were now happily utilizing Windows 10 workstations. His web servers were running Windows Server 2016, and the SQL boxes were up to SQL 2016. Plus his nemesis Ralph had since retired. Or died. Nobody knew for sure. But things were good.

Despite all these efforts, there were still several systems that relied on Access 97 haunting him every day. Jesse spent tens of dollars of his own money on well-worn Access 97 programming books to help plug holes in the leaky dike. The A97 Finance system in particular was a complete mess to deal with. There were no clear naming guidelines and table locations were haphazard at best. Stored procedures and functions were scattered between the A97 VBS and the SQL DB. Many views/functions were nested with some going as far as eight layers while others would form temporary tables in A97 then continue to nest.

One of Jesse's small wins involved improving performance of some financial reporting queries that took minutes to run before but now took seconds. A few of these sped-up reports happened to be ones that Shane, the owner of the company, used frequently. The sudden time-savings got his attention to the point of calling Jesse in to his office to meet.

"Jesse! Good to see you!" Shane said in an overly cheerful manner. "I'm glad to talk to the guy who has saved me a few hours a week with his programmering fixes." Jesse downplayed the praise before Shane got to the point. "I'd like to find out from you how we can make further improvements to our Finance program. You seem to have a real knack for this."

Jesse, without thinking about it, blurted, "This here system is a pile of shit." Shane stared at him blankly, so he continued, "It should be rebuilt from the ground up by experienced software development professionals. That's how we make further improvements."

"Great idea! Out with the old, in with the new! You seem pretty well-versed in this stuff, when can you start on it?" Shane said with growing excitement. Jesse soon realized his response had backfired and he was now on the hook to the owner for a complete system rewrite. He took a couple classes on C# and ASP.NET during his time at Totally Legit Technical Institute so it was time to put that valuable knowledge to use.

Shane didn't just let Jesse loose on redoing the Finance program though. He insisted Jesse work closely with Linda, their CFO who used it the most. Linda proved to be very resistant to any kind of change Jesse proposed. She had mastered the painstaking nuances of A97 and didn't seem to mind fixing large amounts of bad data by hand. "It makes me feel in control, you know," Linda told him once after Jesse tried to explain the benefits of the rewrite.

While Jesse pecked away at his prototype, Linda would relentlessly nitpick any UI ideas he came up with. If she had it her way, the new system would only be usable by someone as braindead as her. "I don't need all these fancy menus and buttons! Just make it look and work like it does in the current system," she would say at least once a week. "And don't you dare take my manual controls away! I don't trust your automated robotics to get these numbers right!" In the times it wasn't possible to make something work like Access 97, she would run to Shane, who would have to talk her down off the ledge.

Even though Linda opposed Jesse at every turn, the new system was faster and very expandable. Using C# .NET 4.7.1 with WPF, it was much less of an eyesore. The database was also clearly defined with full documentation, both on the tables and in the stored procedures. The database size managed to go from 8 GB to .8 GB with no loss in data.

The time came at last for go-live of Finance 2.0. The thing Jesse was most excited about was shutting down the A97 system and feeling Linda die a little bit inside. He sent out an email to the Finance department with instructions for how to use it. The system was well-received by everyone except Linda. But that still led to more headaches for Jesse.

With Finance 2.0 in their hands, the rest of the users noticed the capabilities modern technology brought. The feature requests began pouring in with no way to funnel them. Linda refused to participate in feature reviews because she still hated the new system, so they all went to Shane, who greenlighted everything. Jesse soon found himself buried in the throes of the monster he created with no end in sight. To this day, he toils at his computer cranking out features while Linda sits and reminisces about the good old days of Access 97.

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!