Live data from Hacker News

You've just inherited a legacy C++ codebase, now what?

gaultier.github.io

291–300 of 356 posts

Re: You've just inherited a legacy C++ codebase, now what?

#291

Earlier quoted context omitted.

I think (well, assumed) what they meant by deterministic builds was merely hermetic builds, which are easier. True determinism is overkill for step 0.

Often yes. Sometimes, no. You haven't enjoyed C++ until you get reports of the app intermittently crashing, and your build at the same version just won't. But yes, if the goal is "slap it all in a container", that's probably good and at least somewhat reproducible. We aren't Python here! ;)

That's probably reading uninitialized memory. You can get away with that for a VERY long time, until you can't. See the earlier valgrind recommendation.

But that sort of report isn't a deep mystery, it's just a specific class of bug. Given the description, you've got a pretty good idea of what you're looking for.

Re: You've just inherited a legacy C++ codebase, now what?

#292

Earlier quoted context omitted.

Step 0: reproducible builds (like you said) Step 1: run all tests, mark all the flaky ones. Step 2: run all tests under sanitizers, mark all the ones that fail. Step 3: fix all the sanitizer failures. Step 4: (the other stuff you wrote)

Step 0 sounds so easy. Until you realize __time__ exists. Then you take that away, and you find out that some compiler heuristics might not be deterministic. Then you discover -frandom-seed - and go ballistic when you read "but it should be a different seed for each sourcefile" Then you figure out your linker likes emitting a timestamp in object files. Then you discover /Brepro (if you're lucky enough to use lld-link…

> Then somebody comes to your desk and asks if you can also make partial rebuilds deterministic.

This is a good guy. Knows what they need, knows you are smart enough to potentially finally slay the dragon, will fight the bureaucracy on your behalf. Asking a hard ask is rarely beneficial for the asker on the failure side. Don't burn yourself out for it though and don't be afraid to ask hard favors from the asker.

Re: You've just inherited a legacy C++ codebase, now what?

#293
Read it. A little every day until you've passed your eyes over all of it.

Make notes about mysterious things. Check them off once you've figured them out.

Try to find the 'business case' database. You will fail, nobody has one. Make one then, while you're reading the code.

Re: You've just inherited a legacy C++ codebase, now what?

#294

Some good advice here, and some more...controversial advice here. After inheriting quite a few giant C++ projects over the years, there are a few obvious big wins to start with: * Reproducible builds. The sanity you save will be your own. Pro-tip: wrap your build environment with docker (or your favorite packager) so that your tooling and dependencies become both explicit and reproducable. The sanity you save will be…

> wrap your build environment with docker (or your favorite packager) so that your tooling and dependencies become both explicit and reproducable If you want explicitness and reproducibility please don't reach for Docker. Unless you take a lot of care, you will only get the most watered down version of reproducibility with Docker probably luring you into a false sense of security. E.g. pointing to mutable image tags…

I have docker as part of my reproducibility builds. We recently ran into a problem trying to rebuild some old code - turns out the ssl certificates in our older images has expired and so now the code isn't reproducible anyway. One more reason to agree with the idea that docker shouldn't be used.

Though we use docker for a different reason: we are building on linux, targeting linux. It is really easy to use the host system headers or library instead of the target versions of the same - and 99% of the time you will get away with it as they are the same. Then several years later you upgrade your host linux machine and can't figure out why a build that used to work isn't (and since 99% of the stuff is the same this can be months before you test that one exception and then it crashes). Docker ensures we don't install any host headers, or libraries except what is needed for the compiler.

Re: You've just inherited a legacy C++ codebase, now what?

#296

Earlier quoted context omitted.

>> It's a nice idea, but it's hard to do. One person is using VIM, another is using emacs, another is using QTCreator, another primarily edits in VSCode.. Trying to get everyone on the same page about all this is very, very hard. This is what's wrong with our industry, and it's no longer an acceptable answer. We're supposed to be fucking professional, and if a job needs to build a tool chain from the IDE up we need t…

> every single carpenter in the world should use the exact same make and model of saw, for, uh, professionalism reasons

[deleted]

Re: You've just inherited a legacy C++ codebase, now what?

#297
post #252

Earlier quoted context omitted.

Question: Why does some of the product source code look like it is the output of a decompiler? Answer: Our office was in the WTC and was destroyed on 9/11. Luckily everyone got out alive, but then we discovered we had no off-site backups of the source code. In order to continue development, we had to retrieve the released binaries from our customers and decompile them to get back source code.

I see this as a case of: "see, allowing wfh would have saved you there."

No it wouldn't have - 2001 was 4 years before distributed version control. Work from home might have had current copies of some branches checked out on local machines, but nobody would have had full history or code from release branches on their machine.

Re: You've just inherited a legacy C++ codebase, now what?

#298
post #116

Earlier quoted context omitted.

I agree that this helps, although I still think that in general, the default build should never do -Werror, since people may use other toolchains and it shouldn't surprise-break downstream (I'm pretty sure this is a problem Linux distros struggle with all the time..) If it does it only in your fully reproducible CI, then it should be totally fine, of course.

The scripted, packaged docker with toolchain dependencies and _is_ the build. If someone decides to use a different toolchain, the problems are on them.

Open source projects that insist their docker container is the only way to go are going to be an instant reject from me. It's a total copout to just push a docker container and insist that anyone not using it is on their own.

Docker is too fraught with issues for that, and as anyone can attest, there are few things more frustrating in computing than having to follow down a chain of chasing issues in things only superficially related to what you actually want to do.

The least that can be done is for the project to do its best to not be dependent on specific versions, and explicitly document, in a visible place, the minimum and maximum versions known to work, along with a last changed date.

Re: You've just inherited a legacy C++ codebase, now what?

#299
> Get the build working on your machine

Nope. Make a portable/virtualized env, and make it build there. That way it'll build on you machine, in the CI pipeline, on your co-worker's machine, etc etc.

> linters, fuzzing, auto-formatting

No, for at least two reasons:

1) Too risky, you change some "cosmetic" things and something will quietly shift in the depths, only to surface at the worst possible time

2) Stylistic refactors will bury the subtle footprints of the past contributors - these you will need as you walk through the tunnels on your forensic missions to understand Wat The Fuk and Why

Generally, touch as little as possible, focus on what adds value (actual value, like, sales dollars). The teetering jenga tower of legacy code is best not approached lightly.

Work with PMs to understand the roadmap, talk to sales and support to understand what features are most used and valuable. The code is just an artifact, a record of unhappy accidents and teeth-grinding compromises. Perhaps there's a way to walk away from it altogether.

Re: You've just inherited a legacy C++ codebase, now what?

#300

Some good advice here, and some more...controversial advice here. After inheriting quite a few giant C++ projects over the years, there are a few obvious big wins to start with: * Reproducible builds. The sanity you save will be your own. Pro-tip: wrap your build environment with docker (or your favorite packager) so that your tooling and dependencies become both explicit and reproducable. The sanity you save will be…

> wrap your build environment with docker (or your favorite packager) so that your tooling and dependencies become both explicit and reproducable If you want explicitness and reproducibility please don't reach for Docker. Unless you take a lot of care, you will only get the most watered down version of reproducibility with Docker probably luring you into a false sense of security. E.g. pointing to mutable image tags…

> If you want explicitness and reproducibility please don't reach for Docker. Unless you take a lot of care, you will only get the most watered down version of reproducibility with Docker probably luring you into a false sense of security. E.g. pointing to mutable image tags without integrity hashes and invoking apt-get are things you'll find in most Dockerfiles out there and both leave open a huge surface area for things to go wrong and end up in slightly different states.

If this is frequently a problem you're doing something wrong, or using such a crappy external library/toolchain that breaks frequently on the same version.

Docker is a way to ensure that the software builds with "the most recent minor version" of some OS/toolchain/libraries.

The reason why you want the most recent version is because of security fixes and bugs.

I agree that you should check integrtiy hashes where appropriate, if you really want to fix versions.

Post reply on HN