?

Log in

No account? Create an account

December 13th, 2009 - Excelsior — LiveJournal

Dec. 13th, 2009

04:04 pm - Эмит дебажной инфы для дотнета

Реф.эмит обладает возможностью генерить дебажную инфу, т.е. привязывать создаваемый IL к произвольным строчкам произвольных файлов, именовать локальные переменные, указывать неймспейсы для дебаггера и так далее. Чуть больше о деталях в бложеке Майка Столла (обязательно почитайте, если вы впервые слышите о возможности эмиттить дебаг-инфо для кодегена):
  * Going from IL offset to source line
  * #line hidden and 0xFeeFee sequence points
  * More caveats about #line
  * How can I debug Just My Code?
  * Compiling a language to C#
  * Debugging a 3rd-party language
  * Debug support for arbitrary state-machines
  * Rolling out a debugger
  * Having debugger-friendly codegen
  * Debugging Dynamically Generated Code (Reflection.Emit)
  * Debugging LCG

В свое время я был в диком восторге от этих штук и мечтал что-ть затестировать на практике. И вот, наконец, выдался шанс!

Я был доволен первые полчаса, пока не наткнулся на жоский затык. Оказывается, если просто эмиттить скоупы и имена локалсов, но не определять сиквенс-поинты для инструкций метода, то никакая дебажная инфа про этот метод заноситься в PDB не будет вообще, ну или будет заноситься, но не будет читаться (если интересно, я юзаю связку IMetaDataDispenser+ISymReader для чтения и ISymWriter для записи). Причем без всякого предупреждения или иксепшна - просто ее не будет и все.

Еще одна подстава ожидала меня, когда я решил воспользоваться симбол-райтером модуля напрямую, в обход методов il-генератора и локал-билдеров. Дело оказалось в том, что дебажная инфа генерится реф.эмитом не в момент вызова соответствующих методов, а тогда, когда вызывается CreateType, поэтому все мое творчество переписывалось нафиг в момент создания сгенеренного типа.

После того, как я допетрил, в чем тут засада, все сразу заработало. Даже удивительно - я ожидал гораздо большего сопротивления =)

Tags:
Previous day (Calendar) Next day