摘要: 虽然内核开发人员从一开始就要考虑多线程的问题,但用户态开发人员曾经有过一段美好的生活:他们只需关心一条线程(多半是UI线程)并且不必在乎太多性能问题:即使你在主逻辑里嵌套了无数层循环都没关系,该死的摩尔定律替你搞定一切问题。进入多核时代后,用户态开发人员终于发现了他们忽略很久的,但及其重要的一个技术点:多线程。朋友,好生活已经结束了,欢迎你来到混乱的时代。我知道现在来写这篇东西似乎不合时宜,因为网上已经有无数文章讨论过多线程问题了,各个社区还开发了一个又一个的线程框架帮你解决烦人的琐事,不过我今天的主要目的是为了引出某个内核开发中的棘手问题(就是7.2要讲的,先按下不表),所以各位看官先放小弟 阅读全文
posted @ 2011-03-27 01:24 gussing 阅读(4330) 评论(6) 推荐(1) 编辑
摘要: 不要再假装自己写的程序没bug了,不可能的,debug工具你早晚得用上。最常见的debug工具非printf(windows上用OutputDebugString函数)莫属,简单方便易学易用,但局限性也是显而易见的,首先它对debugee的影响很大,某些race condition的bug你要多加几个log它就重现不出来了,然后你把log去了发布给客户,结果又成了必现的bug,这种烂事咱们都碰到过,你懂的。其次log能打印的东西有限,有时候你加log追某个变量的值,追到最后发现是其他变量有问题,这时候你又得加log重新跑。最后分析log的过程及其枯燥无聊,而在debug上敲命令分析则充满了乐趣 阅读全文
posted @ 2011-01-24 15:12 gussing 阅读(3097) 评论(0) 推荐(2) 编辑
摘要: IO_STACK_LOCATION很重要,再多聊一点也无妨。上上回我们谈了IO_STACK_LOCATION和那几个重要的函数,当然,我的目的不是扫盲,而是记下一些容易犯错的地方(实际上都是工作中碰到过的钉子)以方便自己回顾。我的记性是如此的差以至于几月不看就会忘记。如果你对这东西没概念,我建议你先多查查WDK文档。上回我们聊了IoCopyCurrentIrpStackLocationToNext和IoSkipCurrentIrpStackLocation的差别(你看我的记性是不是很差,其实是上上回说的),结果把要聊的核心内容给忘了。IO_STACK_LOCATION这坨东西出现的原因很大程度 阅读全文
posted @ 2011-01-23 01:38 gussing 阅读(2712) 评论(2) 推荐(2) 编辑
摘要: 今天我们聊一聊CreateFile,这个名字取的不合适但IO的世界里完全绕不过去的东西,以及与之相关的“namespace”这一概念。我们知道Create的意思是创造,创建,上帝创造了这个世界,指的可不是上帝打开了某样存在的东西(唯物主义者,我知道你们有意见,给我闭嘴…),但这个倒霉的函数要做的却是打开。我们也知道File是文件,windows里面也没有“一切都是文件”的概念,但这个倒霉的函数要做的却是打开所有能返回handle的内核对象。Anyway,CreateFile函数是唯一一个能打开内核对象的handle,并让user mode app来访问的方法。将范围缩小到驱动,这个函数也是唯一 阅读全文
posted @ 2011-01-21 14:34 gussing 阅读(3367) 评论(8) 推荐(4) 编辑
摘要: 今天我们来聊聊IRQL,这是驱动新手的梦魇,想想看多少BSOD是因为IRQL不对引起的。这也是*NIX类内核开发人员最喜欢的吐槽点之一,你看linux里就没有这个概念,我们还不是活的好好的?我偶尔有时候能得着一些空,也会问一样的问题:为毛?为毛要有这东西存在!后来我想通了。我们先聊passive level和interrupt level。passive level是普通级别,同时也是优先级最低的,所有的用户态线程和大部分的内核态线程都会在这个级别上运行。interrupt level则是中断服务例程的运行级别。这两者有差很好理解,几乎所有os教程里都有告诫我们中断服务例程要尽可能快的完成,并 阅读全文
posted @ 2011-01-20 14:39 gussing 阅读(2000) 评论(0) 推荐(1) 编辑
摘要: 如前文所述,nt内核的驱动模型没有完全使用函数调用栈,而是自己山寨出来一个IO_STACK_LOCATION,里面保存了驱动调用序列。我们知道函数调用栈的push和pop都是编译器帮忙弄的,你甚至都可以在完全不了解内幕的前提下写代码,但是驱动开发不一样,调用序列要你自己去关心,何时入栈,何时出栈,栈内保留的什么内容,全部都要照顾好,否则BSOD就在前方不远等你。与IO_STACK_LOCATION有关的函数有以下几个:IoSkipCurrentIrpStackLocation, IoSetNextIrpStackLocation, IoGetNextIrpStackLocation, IoCo 阅读全文
posted @ 2011-01-19 13:54 gussing 阅读(3231) 评论(2) 推荐(1) 编辑
摘要: nt内核的IO模型中,IRP有两类:threaded irp和non-threaded irp,顾名思义,前者跟thread绑定,后者跟thread无关。当一个threaded irp被创建时,创建线程会有一个队列保存该irp,直到irp完成之后才释放。当你试图让这条线程退出时,系统会检测队列看里面是否还有irp没完成,如果有,线程会一直等待,直到所有的irp全部完成。而non-thread irp则正好相反,如果该irp已经返回到了创建它的地方你还继续complete它,BSOD将会发生。Threaded IRP如前面所讲,threaded irp和线程绑定在一起。当user mode程序发 阅读全文
posted @ 2011-01-18 11:32 gussing 阅读(2502) 评论(1) 推荐(2) 编辑
摘要: 最近在看 “all about monods”, 其中第一章举了一个例子,用以说明monod的引入是非常合乎常理的,一点都不让人惊讶,它的例子是这样的:假设有一个data type名叫Sheep,现在有一个需求是求Sheep的父亲,我们很快就把函数写出来了:函数写完了,很高兴,可以拿给QA测试了。第二天QA就怒气冲冲的跑过来说:过不了单元测试!father 多利羊 = 多利... 阅读全文
posted @ 2010-09-19 18:03 gussing 阅读(856) 评论(0) 推荐(0) 编辑
摘要: 初学者,纯练手。haskell的类型系统过于强大,以致写程序时大量时间是跟类型不匹配打交道,不过带来的好处就是一旦编译通过,多半就能work了[代码]最近在做Ninety-Nine Haskell Problems已经做到第80题了 阅读全文
posted @ 2010-08-23 18:48 gussing 阅读(810) 评论(0) 推荐(0) 编辑
摘要: 听从某本书的教诲(应该是code complete吧大概),每年应该学一门新语言以便开阔视野,即使是常年靠写c代码吃饭的,也可以把别家的优点吸收进c代码里得到好处。建议是不错,但实践起来太难了。去年我学的是Python,囫囵吞枣的学了两天也没震撼到我的思维,感觉也就是类库比较多用着会顺手点吧,总之就是气场不合。我想要的效果是那种看完后大发感慨“原来还可以这么思维”,而不是&... 阅读全文
posted @ 2010-06-27 01:42 gussing 阅读(918) 评论(0) 推荐(0) 编辑