Does Nim optimize anything on the way to C? That usually destroys useful information.
I can give you an example from C compilers. Consider a simple loop:
int a[] = ...;
for (int i=0; i<max; i++) {
print(a[i]);
}
Something fishy is printed, so I run it in my debugger, break at some point, and print "i". Gdb can usually do that. Now think about the optimizations a compiler probably did: While the index is incremented by 1, we actually step 4 bytes further due to the int array, so the compiler does i+=4 instead to avoid the multiply by 4 instruction. While i starts at 0, we can instead use the "a" pointer and avoid to add an offset at every loop iteration. The code might actually look like this:
int *a = ...
int end = a + max*4;
for (char* x=a; x < end; x+=4) {
print(x);
}
How can gdb print "i"? The trick is DWARF [0], basically the compiler inserts the information: If you want to print i here, then compute it by i=(x-a)/4.
tldr: #line directives are not enough
[0] https://en.wikipedia.org/wiki/DWARF