I have counter-points to several of these... But this one is my favorite (This didn't go very far, but I loved the idea of it...):
I once wrote a program that opened up all of my code, and at every single code curly brace, it added a macro call, and a guid.
void main() { DEBUGVIKINGCODER("72111b10c07b4a959510562a295cb2ac");
...
}
I had to avoid doing that inside other macros, or inside Struct or Class definitions, enums, etc. But it wasn't hard, and it was a pretty sizeable codebase.
The DEBUGVIKINGCODER macro, or whatever I called it, was a no-op in release. But in Debug or testing builds, would do something like:
DebugVikingCoder coder##__LINE__("72111b10c07b4a959510562a295cb2ac");
(Using the right macros to append __LINE__ to the variable, so there's no collisions.)
The constructor for DebugVikingCoder used a thread-local variable to write to a file (named after the thread id). It would write, essentially,
Enter 72111b10c07b4a959510562a295cb2ac (epoch time)
The destructor, when that scope was exited, would write to the same file:
Exit 72111b10c07b4a959510562a295cb2ac (epoch time)
So when I'd run the program, I'd get a directory full of files, one per thread.
Then I wrote another program that would read those all up, and would also read the code, and learn the File Name, Line Number of every GUID...
And, in Visual Studio, this tool program would print to the Output window, the File Name and Line Number, of every call and return.
And, in Visual Studio, you can step forward AND BACK in this Output window, and if you format it correctly, it'll open the file at that point, too.
So I could step forwards and backwards, through the code, to see who called where, etc. I could search in this Output window to jump to the function call I was looking for, and then walk backwards...
Then I added some code that would compare one run to another, and argued we could use that to figure out which of our automated tests formed a "basis set" to execute all of our code...
And to recommend which automated tests we should run, based on past analysis.
In addition to being able to time calls to functions, of course.
So then I added printing out some variables... And printing out lines in the middle of functions, when I wanted to time a section...
And if people respected the GUIDs, making a new one when they forked code, and leaving it alone if they moved code, we could have tracked how unit tests and other automation changed over time.
That got me really wishing that every new call scope really did have a GUID, in all the code we write... And I wished that it was essentially hidden from the developers, because who wants to see that? But, wow, it'd be nice if it was there.
I know there are debuggers that can go backwards and forwards in time... But I feel like being able to compare runs, over weeks and months, as the code is changing, is an under-appreciated objective.