Il problema ormai è chiuso, dopo la raffica di post di Paolo (qui, qui, qui e qui), Cristian (qui) e Raffaele (qui, qui e qui).
Con un ritardo di una settimana, non faccio adesso altro che aggiungere due ciliegine (2 cents?) sulla torta:
Richter nel suo libro (pp. 443-444) avvertiva:
"Ogni qualvolta si ottiene un'analisi dello stack, è possibile rilevare che alcuni metodi dello stack di chiamate non sono visualizzati nell'analisi dello stack. Il motivo di questa assenza è rappresentato dal fatto che il compilatore JIT può eseguire l'inlining dei metodi per evitare l'overhead generato dalla chiamata e dalla restituzione di un metodo separato. [...] Se si applica l'attributo personalizzato System.Runtime.CompilerServices.MethodImplAttribute a un metodo, sarà possibile impedire al compilatore JIT l'inlining del metodo sia relative alle build di debug che a quelle di rilascio".
La stessa osservazione la faceva anche il mitico Chris Brumme, i cui post, penso, manchino a tutti:
"Incidentally, when you are playing around with stack traces (whether they are associated with exceptions, debugging, or explicit use of the StackTrace class), you will always find JIT inlining getting in your way. You can try to defeat the JIT inliner through use of indirected calls like function pointers, virtual methods, interface calls and delegates. Or you can make the called method “interesting” enough that the JIT decides it would be unproductive or too difficult to inline. All these techniques are flawed, and all of them will fail over time. The correct way to control inlining is to use the MethodImpl(MethodImplOptions.NoInlining) pseudo-custom attribute from the System.Runtime.CompilerServices namespace".
Il comportamento è proprio by design.