This recent report of a TrendMicro vulnerability is very serious, but it made me laugh as I imagined the recipients of Tavis’ pithy wisdom scrambling to react.
The time-worn phrase “There must be a bug in the compiler” is usually a red flag. When I hear this I hear “There’s something wrong with my code, and I’m either too lazy or too inexperienced to figure out what it is.”
An ex-colleague of mine a few years ago approached every problem by reinstalling his software. His compiler, his IDE, maybe even Windows 7. Needless to say, it hardly ever fixed his bug, but that didn’t seem to curb his enthusiasm.
Once he got lucky and a SQL Server reinstall solved all his configuration issues. That was a happy day for him.
What reminded me of him today was this article on recent Intel CPU bugs. He’ll love that, I must send it on to him. I can hear him now: “There’s a bug in my CPU. I need a new laptop.”
But he’s not the only one affected. The increasingly serious implications of CPU bugs are summed up by this line ‘…“unpredictable system behavior” has moved from being an annoying class of bugs that forces you to restart your computation to an attack vector that lets anyone with an AWS account attack your cloud-hosted services…’
I recently came across this article by Dennis Stevenson on why technical debt isn’t necessarily a bad thing, which struck a chord with me.
Personally, I’m all about the refactoring.
One startup I worked with around 2000 had a market-leading product. It was fun, different, simple to use and facilitated a unified approach to employee help in the corporate environment. The company had a dynamic sales force selling the product in the US. They had a foot in the door of some of the very big players.
The code was kind of kludgy though. It didn’t work quite right here; there was an issue or two there. The lead developer, who reputedly was a genius (he was gone by the time I got there) decreed that everything should be torn down and rewritten.
This was duly done, by him. Commercial databases weren’t fast enough apparently, so he wrote a proprietary flat-file DB system that rendered the entire contents of the DB inaccessible except through his code. (In fairness to the man, this was around 2000 and SQL Server was only on version 1, or 2, or maybe 5 or 6 or something, and MySLQ was only a tiny baby, but Oracle was out there. And there was Sybase…)
As regards the GUI and business layer, he used his comprehensive knowledge of C++ to create an incomprehensible structure of classes and templates, bristling with design patterns added in the name of extensibility. A pattern in the right context is a thing of beauty. But…patterns piled in together to deal with imaginary future needs create unnecessary problems for everyone who’s not the program author.
Anyway. That was all lovely. At the end of a year or so Version 2 was unveiled.
It was a joy to behold.
There were a few new bugs that hadn’t been there before. There were a couple of Version 1 features that hadn’t made it in yet. And no actual new features, as such (unless you count the shiny, proprietary, and infinitely corruptible flat-file database, and the design-patterny code in the background).
But no worries, because it was so much more extendable now. And blazingly fast because of the DB (actually, it wasn’t blazingly fast but there was probably some non-DB-related reason for that).
Then he left.
I was one of the army of software consultants hired to fix the bugs, provide out-of-application access to the DB and maybe add a feature or two.
There were a few UML diagrams of the new DB structure, but (as always happens in my experience) every detail you might actually need to know when accessing it was undocumented. These had to be figured out the hard way. There were so many unnecessary bells and whistles in the business layer, added for future extendibility, that it was extremely difficult to figure out how to add any features.
Coincidentally, the Agile Manifesto was launched around then. Too late, alas, for us.
The writing was on the wall. Customers were sick of waiting for absolutely essential features. To give one example, you couldn’t select multiple files in the GUI. If you wanted to move a few files from one project to another you had to drag them one by one. And the most enthusiastic customers had hundreds of files in their projects.
Soon the company could no longer afford its new developer army.
Soon afterwards, it went bust.
(Some years later, I got a job creating a system to stream real-time stock-market data. One of the things I was told on my first day was that conventional DBMSs weren’t fast enough… I’ll tell you my antennae sprang up damn fast. It was true in that context though.)
So, what would have happened if the Big Rewrite hadn’t?
Well, I wasn’t familiar with Version 1, but here’s what I think:
– Developers would have refactored where they could, as they went along
– Someone would maybe have spent a month or two figuring out how to speed things up WITHOUT a proprietary DB system
– New features would have been added a year earlier. And then more new features, and then more…
– The users would have been happy, and would have pushed for the software to be retained by their employers
– The company would have had some small chance of riding the .dot con storm that was on the horizon
So yes. Version 1 was littered with Technical Debt, but Technical Debt, as Stevenson says, can be a good thing. It means you’ve been around long enough to evolve past Version 1, and you’re still here. Keep your Sensible hat on, bank that debt, and get yourself a copy of Michael Feathers’ ‘Working Effectively with Legacy Code’.
When I started in one role, I found that there was no source control or issue tracking system in place for my very small team.
No source control was something I hadn’t seen since 1997. I absolutely could not write code without source control. I had Git set up after a couple of days.
Then I turned my attention to issue tracking. My constraints were as follows:
1) No management support
2) No budget.
When considering a choice of issue logging system I had the following criteria in mind:
1) Free (that ruled out Jira and TFS, the two systems I’d used most recently)
2) Source code integration
3) Windows OS
4) Can create tickets
5) Can see history
6) Can view reports
7) Easy to install (there was no time allocated for me to do this)
8) Easy to use (or I wouldn’t get buy-in from my new colleagues)
9) Easy to extract data if upgrading to e.g. Jira later
I hunted around and made up a list of potential candidates. I quickly ruled out the following, which at a glance had looked promising:
BugLogHQ – provides a unified view of error messages sent from applications and servers – not what I wanted.
LogDigger – is to monitor your Java app health
Bugify – not free
More research yielded the following table:
|Mantis Bug Tracker
By this stage I was starting to abandon my scientific approach. There was something attractive about Trac. Intending to check out more details of the other systems later, I started fiddling around with the Bitnami Trac install. Surprisingly quickly it was up and running on my machine. IJW. I like it.
Although I explained to my new team what it was and what it was for, Trac was regarded with suspicion at best. The first few defects were all logged by me. There’s no way to force adoption of these things. (At least, there’s no way to force it if you’re a software consultant who’s only just arrived in the office.) Progress was slow, but the interface is clean and quick and easy to use, so I had high hopes.
Then the work started to happen.
By the end of the first year. over 900 issues had been logged and processed via Trac. It never gave us any issues. After a few months I transferred it off my PC to a vm, easily and quickly with no loss of existing data.
It’s highly extendable but everything we needed was there out of the box. I only added one plugin, to change the workflow to allow for a ‘testing’ status.
The source code integration is simple, gives you lots of unexpectedly useful tools including colour-coded revision logs, and provided a great sanity check for the status of our central Git repository.
I highly recommend it.
I had to do this recently, and Googling wasn’t much help. So in case any of you are in the same boat…
Do a search and replace (Ctrl+h).
In the ‘Find what’ box, leave the text blank. Click the ‘format’ button and choose ‘font’. Select the particular font, font-size, bold etc combination used for the heading you want to convert to a style.
In the ‘Replace with’ box, also leave the text blank. Click the ‘format’ button and choose ‘Style’. Click ‘Replace all’.
All your selected text should now be set to the relevant style.
You may find that the style isn’t properly applied. For example, the colour may have changed but the font and font size may have stuck.
To correct this, open the Styles pane. Right-click the desired style and choose the ‘Select all x instances’. Then left-click the style. All your newly-converted text will fully update to the desired style.
As a software contractor – or as I say to my parents, consultant – I’ve discovered several natural rules over the years. You can learn them the hard way, or you can read my blog. This is The First, Top and Most Essential rule of software contractng.
Consultant’s Rule 1: If it’s not broken, don’t fix it
As a contractor, you’ll regularly arrive in a new company, with a whole new lot of code to mess around with. Monolithic. Archaic. Spaghetti. All terms that could apply to many mounds, sorry, heaps of code you’re likely to encounter.
The temptation is to fix it. Now. At once, and everywhere.
I see newbies do this all the time. I’ve been there myself. “Oh, these thirty lines of code are repeated here. And here. And…here…and here OMG who WROTE this?…and here…I know, I’ll pop them into a neat little function and call it from all over the place.”
Sounds like a good idea, right?
Sure. If you missed any little breaking differences across the twenty implementations, your mistake will be picked up by the automated unit tests.
Um, what automated unit tests?
Some companies do indeed maintain automated unit tests, and even run them occasionally, but are the tests documented? Do they cover the code you’re planning to change? All of it? Every possible instance?
TBH, in a contracting situation you probably don’t yet know how to run some of the classes you’re planning to change – no idea how to get to the place they’re called from at runtime – do you have time to research and test twenty different use cases? You only managed to get the code building yesterday. Oh and by the way, What are you actually SUPPOSED to be doing? Easing your way into the software by fixing a priority 3 bug…so why are you changing a file in a whole different module?
‘So. What?’ you ask. I’ve got to leave that stuff there, steaming gently, waiting for the next idiot to break it instead?’
No. Here are your options:
Point out the issue to your boss and ask for permission to change the twenty instances you’ve found, replacing them by a simple function call.
Good luck with that. They didn’t hire a contractor to refactor their code to perfectly match the structure recommended in universities. They know the software is kludgy, but it seems to work. They hired you to implement some new feature, or expedite a release that they consider business critical. There isn’t time to test your changes. Oh and by the way, your boss probably wrote some of the code you’re dissing right now.
Note, though, that this is the correct approach if you’ve identified an issue which is causing or is highly likely to cause a serious bug.
Don’t say anything to your boss, who looks rather busy. Just go ahead and do it, you’re a professional, you won’t make any mistakes.
Sometimes you’ll slip your changes through, but generally you’ll break a piece of functionality you didn’t know existed. Best case, you’ll delay a release. Worst case, you won’t delay the release and the first your boss will hear about your bug will be from floods of irate customers. Your name will be mud. How much are they paying you again?
Option 3 (for refactoring code that currently works, this is what I recommend)
Do things right for the particular bug or feature you’re working on. Create the function even though you’ll only call it once. Pay attention to function parameters, and to where you locate the function in the code, so it’ll be easy to reuse later.
Optionally, insert a todo comment in all the places you’d like to call your new function from, mentioning this useful function and where to find it.
Commit your fix / feature and tests.
Bide your time.
Later (maybe even six months later) you’ll find yourself working on the areas of code that would benefit from your super-cool function. Off you go. Delete all those useless redundant lines. Call your function instead. Your changes will (hopefully) be tested, because they’re in an area you are in fact supposed to be changing.
As you settle into a new job and become more familiar with the application you can relax a little. You’ll acquire a better grasp of implications and you’ll have some kind of automated test regime in place. (Won’t you?)
Eventually you should be in a position to make sweeping changes with confidence.
Conclusion: Refactoring is wide-ranging and incremental. You can repeat Option 3 above over and over again, until the code base is full of improvements and most of them are in use.
Guiding Principle: Never change anything without having a comprehensive test plan in place.
Shipping was charged twice for my product by the WP e-commerce plugin when shipping was set to ‘flat rate’.
I googled it and found that this problem has been recorded, but with no solution posted and the discussion closed.
Turns out it’s not a bug, it’s just a configuration issue. I incorrectly entered a base shipping charge as well as a product-specific shipping charge.
The solution is to set all charges to zero in the Settings – Store – Shipping – Shipping Modules – Flat Rate – Settings screen.
Set the shipping charges you want in the product-specific screen.
Then, of course, test thoroughly to ensure you have the charges you expect.
In 2005 I had the good luck to be the first to spot a minor error in Scott Meyers’ classic book ‘More Effective C++’. He keeps meticulous records, so you can see the details here – search for 5/25/05.
This is my greatest claim to C++-Nerd-dom, but if you want more proof, I have actually read all of Alexandrescu’s ‘Modern C++ Design’. Even the bit on Symmetry with the Brute-Force Dispatcher.
I had this problem after we lost a domain name for a Joomla! site.
I copied the Joomla! site back onto the server using a new domain name, which allowed us to use the same database. There were two issues:
– I had to change some configuration settings, but Joomla! reported that it couldn’t save configuration.php. I ended up changing it via Filezilla.
– Virtuemart displayed nothing until it was configured to use the new domain name (see this post on that topic.)
Once I had the site running and looking ok I had to update the theme. This was impossible because of the write permissions issue. I couldn’t write to any location on the server via Joomla! I tried everything in this useful post, but no joy.
The website is running on IIS 6.
I found a setting on the hosting site’s control panel called ‘Website Write Permissions’, and ticked it. This fixed the Joomla! write permissions, but what else does it do?
Next step: update to the latest versions of Joomla! and Virtuemart, and urgently review site security.