Published on by

UPDATE (2017/01/07):

Unwanted telemetry added into all executables built using Visual Studio 2015 prior to Update 3 (which I was the first to notice and write about below) has been picked up by other developers four months later on Reddit, and MSVC Dev Manager Steve Carroll has issued an official statement which you are advised to read.

If I wanted to be snarky about it (and I always do when someone violates my privacy by doing shady things behind my back) I'd say that his statement reads like "sorry we got caught" sort of a non-apology. The only positive is that due to the public outcry the unwanted telemetry code got removed from the CRT with Visual Studio Update 3. The light bulb thing in the editor still sucks though.

ORIGINAL ARTICLE:

Yesterday I installed a trial version of Visual Studio 2015 Professional.

I fired up a C++ project, it compiled and with /arch:SSE2 selected I still got x87 FPU instructions in the mix. Hey Microsoft compiler team, 1980 called, they want their 8087 chip back.

Then I looked at the resulting DLL file with hex editor and I saw this:

__telemetry_main_invoke_trigger
__telemetry_main_return_trigger

Both functions imported from VCRUNTIME140.dll. They get executed before and after actual DllMain() is called as can be seen in CRT source code found in crt/src/vcruntime/dll_dllmain.cpp:

        if (reason == DLL_PROCESS_ATTACH)
        {
            __telemetry_main_invoke_trigger(instance);
        }

        result = DllMain(instance, reason, reserved);

        // If the client DllMain routine failed, unwind the initialization:
        if (reason == DLL_PROCESS_ATTACH && !result)
        {
            DllMain(instance, DLL_PROCESS_DETACH, reserved);
            dllmain_crt_dispatch(instance, DLL_PROCESS_DETACH, reserved);
            dllmain_raw(instance, DLL_PROCESS_DETACH, reserved);
        }

        if ((reason == DLL_PROCESS_ATTACH && !result) || reason == DLL_PROCESS_DETACH)
        {
            __telemetry_main_return_trigger(instance);
        }

Similar code exists for EXE files and it gets invoked before and after main(). Also, in the crt/src/vcruntime/vcruntime_internal.h, Microsoft helpfully explains... well, you guessed it, nothing whatsoever:

//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
// Telemetry
//
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// Telemetry: Invoked when the exe/dll are invoked. There are two different
// implementations in telemetry.cpp and telemetrydefault.cpp. Because GetModuleFileName
// is not available for Store apps, we return an empty string in telemetrydefault.cpp
// when invoked by store apps. For the desktop in telemetry.cpp, it returns the name
// of the module which invokes main/dll. This method is also responsible for firing the
// events associated with Tracelogging. This will help with runtime telemetry for analysis.
void __cdecl __telemetry_main_invoke_trigger(const HINSTANCE instance);

// Telemetry: Invoked when the exe/dll are shutdown. There are two different
// implementations in telemetry.cpp and telemetrydefault.cpp. This method is
// responsible for firing the events associated with Tracelogging. This will
// help with runtime telemetry for analysis.
void __cdecl __telemetry_main_return_trigger(const HINSTANCE instance);

My attempts to find telemetry.cpp and telemetrydefault.cpp were in vain because they are not included in the CRT source tree. With so little information about this functionality I don't even understand whether this feature was designed to benefit me as a developer or just Microsoft? Because if it is the latter then I have a few questions to ask:

1. Don't you think that having to pay for the privilege of using your development tools (compared to Linux and OSX where development tools are complimentary) is already enough monetization of your customers?

2. Don't you think that our customers might not like the idea of the unsolicited and impossible to opt-out of telemetry baked into our executables built using your product?

I certainly don't like the idea of more unnecessary code executing before and after my own. When we are at it, I also don't like forced updates in Windows 10. I don't like the OS which does whatever it wants 90% of the time without even considering what I might be doing on the computer. But enough digressions, let's get back to Visual Studio.

I decide to set telemetry aside and I sit down to write some code. As soon as I write a prototype for a function named Foo(), it immediately gets underlined with a green squiggle which says Function definition for "Foo()" not found.

Hmm... of course it is not found when I haven't written one yet. Thank you, Captain Obvious. Click, click, click... nope. It won't go away. Options? Nope. Project Settings? Nope. What should I do if I never want to write a definition because it is just a prototype for a library function or for a function defined in another file? What then?

Retarded Quick Actions a.k.a. Light Bulb feature in Visual Studio 2015 won't stop bugging me. Whoever thought introducing that was a good idea is out of their fucking mind. The green squiggle is equally distracting as the red one. It is begging for attention which should be elsewhere, on writing high-quality code instead of instant gratification of form over function. And what it has in common with telemetry? It cannot be disabled.

Now excuse me, I have an Uninstall button to click. On a bright side, Mac OSX and even Linux (gasp!) are looking better and better with every new Microsoft software release.