Other Dump source code during execution like a debugger or more or less like a coverage tool

I have this little problem: I'm currently implementing pci listing in a port (Unreal Engine for those who've seen me before on this forum) and I want to use some of the code from pciconf.

What I'm looking for
Now it would be very handy if there were a utility I could call that would take that executable (with debug info or instrumented) and simply dump the corresponding lines of the source as they execute.
I wouldn't have to sift through lines of argument filtering for stuff that isn't relevant for this one call, trying to follow code paths manually, switch between source files etc.

So ideally what I'm looking for would be something like this
<utility> ./pciconf.debug
which would in turn create a file with all lines of code like they appear in the source code in order of execution. That last part is quite important, because I've been wanting to use such a tool on bigger executables as well.
Having this small source listing with only the paths that are effectively executed would make it much easier to understand how something works. No more clutter, no manual traversing code. Just run it and look at the filtered sources, possibly with file names and lines.

The best I can come up with
I could use lldb, the llvm debugger to run the code, step it and copy each line of source one by one. It'd work, but it wouldn't be very time-efficient.
I know there's some scripting in lldb, but as far as I know that's only in Python which I'm not proficient with. I also don't know if what I want would be possible at all.

One way I've found is to run the llvm code coverage tool llvm-cov, which results in a source listing where I at least see what code has or hasn't been executed.
Thanks to that coverage I also know that of the 2440 lines of code (including empty lines etc):
  • 1635 lines were instrumented never run
  • 243 lines were effectively executed (about 10%)
  • (and the remaining lines are either empty, function headers, include statements etc; all non-code lines)
And if it means loops are unrolled or anything like that, I'd be fine with it. If it doesn't, even better. It's just about having a nice way of sequentially following a path of execution.
I'm looking through these 243 lines and am thinking that it would be even better if if-statements and conditionals would be resolved. But I'll settle for something less-advanced :)