活久见:表达式树编译执行引发VerificationException—操作可能会破坏运行时稳定性
作者:V君 发布于:2018-2-7 0:04 Wednesday 分类:挖坑经验
TL;DR:
当在使用表达式树编译成员绑定表达式,且存在隐式值类型装箱,
将表达式树编译成的委托执行起来的时候将会引发异常VerificationException,
并提示消息“操作可能会破坏运行时稳定性”。
解决方法为显式装箱之后再绑定,可能是表达式树在编译成IL时没有对其进行必要的校验。
至于是不是性能考虑就不晓得了。从结果上来看,似乎却在运行时(亦或者JIT时)有检查。
听我扯扯:
在项目中需要比较两个同类型对象实例,且将差异收集起来。
于是咱首先就想到:不要一遍遍写繁琐的判断!
而是使用动态行为——堆IL、拼代码动态编译或表达式树编译。
咱选择后者,比起堆IL和拼代码还是表达式树写起来更舒服。
就算使用动态行为,基础的动作还是由简单的逻辑语句组成。
首先要遍历要diff的类的全部属性,然后将两个实例对应的属性值读出来比较,
若值相等则忽略,若值差异则连同属性名和两个差异的值收集起来。
思路想清楚了就开始吧。
定义一个有3个属性的类,分别存放属性名,和两个值,作为差异条目模型。
命名DiffEntry,属性名是字符串,另外两个是object。
接着定义一个静态泛型类,静态构造里面构建每个属性的比较表达式树并将它们编译成委托,
公开静态方法Diff,返回DiffEntry的数组,调用编译好的委托。
命名ObjDiffCollector,存在引发装箱异常问题。
在gist描述为修订2,因为最初使用数组存放编译出来的委托,发生异常之后,
为了调查异常引发原因缩小范围,改为字典,键是属性名,值是委托,仅用在调试查看。
将问题缩小到值类型在DiffEntity的构造初始化成员绑定之后,
.↑字符串类型没有问题
开始一小会儿的懵逼,放狗出去并没有找到什么卵线索。
这段可以忽略
先贴上异常名称,咕狗很贴心地提示了“operation could destabilize the runtime”,
接着出来的只有一个爆栈帖子,提到使用一个第三方数据访问层引发这样的错误。
打住吧,换成中文消息搜一下看看。
和预料的一样然并卵,被一篇转载到成为互联网垃圾程度的文章刷屏。
文章清一色的提到使用redgate的性能测量库所引发。
到这里线索断了。时间也不早,还要赴约,就把问题撂下跑了。
离开电脑面前不久之后,又玩了一次当局者迷play。
在外头晃悠时忽然灵光一现想到可能是隐式装箱导致,最终证实这个想法。
THE MEAT AND POTATOES 圈重点啦
可能堆IL和表达式编译一样,没有经过太完整的代码转换过程,隐式行为需要显式表达。
这时候需要将绑定的表达式加一层,转换成object,也就是显式装箱。
最终得出可用的ObjDiffCollector。
回过头来想一想,发现CLR报这个错误也不无道理。
试想一下:一个非引用类型的结构体被装箱的情形,如果再复杂一点如果和原生代码扯上关系。
可能会导致意外的值复制行为,从而影响到整个应用程序的稳定性。
想当年,玩DllImport时,一不小心就内存损坏或者堆栈不平衡……
到此为止啦,收工!
接下来该考虑如何一步到位了,或许可以在一个表达式里面作完所有属性的比较和收集差异。
让代码的逼格显得更高。 乂目
标签: 软件开发 C# 调试技术 JIT LINQ 运行时错误
排查ASP.NET响应迟钝.用DebugDiag分析转储,再用WinDbg+sosex查看调用参数
作者:V君 发布于:2017-6-9 17:01 Friday 分类:填坑经验
WEB应用程序出现响应很慢甚至卡死的现象,
Server Admin 通过 DebugDiag 分析转储发现有个请求特别耗时间 (一个小时以上)
于是锅放到我这里辣.
DebugDiag得出堆栈已经显示具体代码位置了,
想知道哪些数据被操作,还需要知道传入了哪些参数,这时候必须请出WinDbg+sosex了.
参考其 sosex 的 readme.txt 或 MSDN文章 得知 !mk 命令可以查看当前线程调用堆栈
要切换当前线程 使用 ~*s 命令 (更多命令参见 windbg.info文章 )
搞起! 先 .load sosex 再 ~*s 然后 !mk 这样就可以看到刚才的堆栈了,确保没选错线程
然而参数还没出来... 别急,呔! !mdso 列出当前线程堆栈上下文对象值
这个命令支持使用参数 /t:类名 来筛选结果. 这次排查过程顺利得有些出乎意料哇 乂目.
记一次COOKIE域造成ASP.NET会话丢失
作者:V君 发布于:2017-5-24 16:05 Wednesday 分类:填坑经验
TL;DR
从浏览器 COOKIES 开始检查, 注意每次请求时 asp.net_sessionid 是否有变化,
注意响应 COOKIES 是否有设置 Domain. 于是发现为了兼容子域名被设定了值.
加上调试条件编译跳过就解决了.
稍稍扯扯:
最初,发现 ajax 请求没有返回预期内容, 调试发现 Session 里面的东西变 null 了.
第一反应是Session配置问题或可能被 Abandon 过, 全文检索代码没发现被调用.
先排除被 Abandon 这个可能.
去 web.config 看看 Session 配置, 切换了 InProcess 和 StateService 模式都不奏效.
然后观察每次请求上下文,发现 SessionId 每次都会变,COOKIE asp.net_sessionid 也每次都变
最后只好把焦点放到浏览器了, 仔细观察 COOKIE 响应状况发现了原因.
Mono Android WebView 应用初体验[Updated]
作者:V君 发布于:2017-2-16 20:38 Thursday 分类:折腾手记
Hybrid App 这个技术诞生的时间很早, 到现在已经颇为成熟.
虽然略有所闻, 也在 Windows forms 上面用 CEF 玩得很溜, 但还是没去实际接触开发.
由于最近有想折腾的玩意儿, 况且公司在不久之后有需要做APP的可能.
就开始去接触吧!
略去安装开发环境的过程, 打开 VS2015. (当然要用我大井来写, 做什么都要用我大井才爽啊)
首先新建 WebView 项目, 然后观察.
和常见的 Android 项目一样, 也见到了熟悉的 Assets Resources MainActivity 这些玩意儿.
不过多了 Models 和 Views 这两个文件夹.
MainActivity 的模板初始化代码也从按钮事件处理, 替换成了 WebView 视图初始化.
还没来得及纠结如何实现页面与原生功能交互时, 已经能看到模板类 HybridWebViewClient 了.
虽然方式有点土, 只能通过请求拦截来实现调用原生代码.
但这已经满足了 APP 开发的最低要求.
那问题来了: (挖掘机哪家强) 跑在手机应用的网页要怎样调试脚本呢?
我们知道 Chrome 的 F12 很好用, 但 APP 能这样整吗?
答案是可以! 咕狗关键字 Android Web View Debug 第一条就找到了官方文档.
官方文档也是先 TL;DR 地列出3个粗略的步骤, 然后再对其逐一详细解释.
1) 启用 WebView 调试属性.
2) 开个Chrome浏览器访问 chrome://inspect 这个 URI.
3) 在页面上列出的视图列表上找到你的应用对应视图, 点击 inspect 链接.
山口山! 一个 F12 工具蹦出来了! 鼠标在元素列表上划过, 手机端视图也和浏览器一样高亮!
整个就像是 Chrome的 F12 一样! (´∀((☆ミつ 本来这就是 Chrome 的 F12!
初体验结束. 接下来可以愉快地写 APP 辣!
Update:
发现要做到这样调试还有一个前提, 也就是需要科学咳咳. 不信你就看 → git/issues
在另一台机做了同样操作,发现白屏了,咕狗一下才知道原来只要这样搞.
因为一直都有自动电梯, 所以没察觉到有这要求...
标签: 软件开发 调试技术 移动端 Android HybridApp
使用Debug Diagnostic Tool分析.net转储
作者:V君 发布于:2016-10-25 11:26 Tuesday 分类:填坑经验
TL;DR:
去M¥官网下载该工具, 对应其x86/x64. 安装时选择关联文件类型.
装好之后双击要分析的dmp文件. 等一会儿. 一个可视化的mht分析报表就出来了.
注意这工具只能在Vista(NT6)以上环境运行.
转储dmp文件可以用Sysinternals出品的免费系统工具Process Explorer来做.
听我扯扯:
虽然WinDbg+sos/sosex很强大, 但是用起来很复杂, 载入符号也很慢.
于是找到了这货来帮忙, 尽管和前者比起来就差不能在内存中找对象.
但是非常方便收集异常信息以及线程堆栈.
blogger
Google Web Translator
热门日志
随机日志
最新日志
最新评论
- V君
@Quartz:(出现)... - Quartz
怎么不见人了呢... - V君
@Soar:DHCP 协议相... - V君
@Soar:当然是非... - Soar
@V君:谢谢 有空... - Soar
搞一个 1230v3+B85... - V君
@Soar:另外,也可... - V君
@Soar:iscsi服务端... - Soar
难怪这么卡,尤其... - Soar
clone了源码,提示...
分类
存档
- 2024年5月(1)
- 2023年7月(1)
- 2023年5月(1)
- 2022年11月(1)
- 2022年10月(1)
- 2022年9月(1)
- 2022年8月(1)
- 2022年7月(1)
- 2022年6月(1)
- 2022年5月(2)
- 2022年4月(1)
- 2022年3月(1)
- 2022年2月(1)
- 2022年1月(1)
- 2021年12月(1)
- 2021年11月(1)
- 2021年10月(1)
- 2021年9月(1)
- 2021年8月(1)
- 2021年7月(1)
- 2021年6月(1)
- 2021年5月(1)
- 2021年4月(1)
- 2021年3月(1)
- 2021年2月(1)
- 2021年1月(1)
- 2020年12月(1)
- 2020年11月(1)
- 2020年10月(2)
- 2020年9月(1)
- 2020年8月(1)
- 2020年7月(1)
- 2020年6月(1)
- 2020年5月(1)
- 2020年4月(2)
- 2020年3月(3)
- 2020年2月(1)
- 2020年1月(1)
- 2019年12月(1)
- 2019年11月(1)
- 2019年10月(1)
- 2019年9月(1)
- 2019年8月(2)
- 2019年7月(1)
- 2019年6月(1)
- 2019年5月(1)
- 2019年4月(1)
- 2019年3月(1)
- 2019年2月(1)
- 2019年1月(2)
- 2018年12月(2)
- 2018年11月(1)
- 2018年10月(3)
- 2018年9月(4)
- 2018年8月(6)
- 2018年7月(4)
- 2018年6月(1)
- 2018年5月(2)
- 2018年4月(2)
- 2018年3月(3)
- 2018年2月(1)
- 2018年1月(1)
- 2017年12月(1)
- 2017年10月(2)
- 2017年9月(1)
- 2017年8月(2)
- 2017年7月(1)
- 2017年6月(5)
- 2017年5月(2)
- 2017年4月(2)
- 2017年3月(3)
- 2017年2月(2)
- 2017年1月(2)
- 2016年12月(3)
- 2016年11月(2)
- 2016年10月(3)
- 2016年9月(4)
- 2016年8月(2)
- 2016年7月(4)
- 2016年6月(3)
- 2016年5月(1)
- 2016年4月(4)
- 2016年3月(3)
- 2016年2月(1)
- 2016年1月(5)
- 2015年12月(4)
- 2015年11月(5)
- 2015年10月(1)
- 2015年9月(6)
- 2015年8月(4)
- 2015年7月(1)
- 2015年6月(6)
- 2015年5月(3)
- 2015年4月(3)
- 2015年3月(2)
- 2015年2月(1)
- 2015年1月(3)
- 2014年12月(1)
- 2014年11月(1)
- 2014年10月(1)
- 2014年9月(3)
- 2014年8月(1)
- 2014年7月(1)
- 2014年6月(1)
- 2014年5月(3)
- 2014年4月(1)
- 2014年3月(1)
- 2014年2月(2)
- 2014年1月(1)
- 2013年12月(2)
- 2013年11月(2)
- 2013年10月(1)
- 2013年9月(3)
- 2013年8月(14)
- 2013年7月(7)
- 2013年4月(1)
- 2013年3月(4)
- 2013年2月(6)
- 2013年1月(6)
- 2012年12月(8)
- 2012年11月(6)