UTF8 + BOM产生问题与小结

写python脚本的时候发现这样一个问题:从xls文件导出到txt时,无法直接转换为int型数据,输出查看发现和文件编码方式产生的附加信息有关用一个简单的文件举例

当文件分别用ascii,utf8,utf8+bom作为编码格式时,显示输出结果如下:

使用ascii编码的输出:

使用utf8编码的输出:

使用bom编码的输出:

原来utf8+bom不能直接转换int的原因在这里,它在文件头插入了一个表示文件编码的信息\xef\xbb\xbf,那么UTF-8(无BOM)和UTF-8这两个有什么区别呢?BOM是什么呢?

什么是BOM?

BOM: Byte Order Mark

UTF-8 BOM又叫UTF-8 签名,其实UTF-8 的BOM对UFT-8没有作用,是为了支持UTF-16,UTF-32才加上的

BOM,BOM签名的意思就是告诉编辑器当前文件采用何种编码,方便编辑器识别,但是BOM虽然在编辑器中不显示,但是会产生输出,就像多了一个空行。

Byte Order Marks are special characters at the beginning of a Unicode file to indicate whether it is big or little endian, in other words does the high or low order byte come first. These codes also tell whether the encoding is 8, 16 or 32 bit. You can recognise Unicode files by their starting byte order marks, and by the way Unicode-16 files are half zeroes and Unicode-32 files are three-quarters zeros. Unicode Endian Markers

Byte-order mark Description
EF BB BF UTF-8
FF FE UTF-16 aka UCS-2, little endian
FE FF UTF-16 aka UCS-2, big endian
00 00 FF FE UTF-32 aka UCS-4, little endian.
00 00 FE FF UTF-32 aka UCS-4, big-endian.

UTF的字节序和BOM

UTF- 8以字节为编码单元,没有字节序的问题。UTF-16以两个字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的字节序。例如收到 一个“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。如果我们收到UTF-16字节流“594E”,那么这是“奎”还是 “乙”?

Unicode规范中推荐的标记字节顺序的方法是BOM。BOM不是“Bill Of Material”的BOM表,而是Byte Order Mark。BOM是一个有点小聪明的想法:

在 UCS编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前,先传输 字符"ZERO WIDTH NO-BREAK SPACE"。

这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little-Endian的。因此字符"ZERO WIDTH NO-BREAK SPACE"又被称作BOM。

UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8编码是EF BB BF。所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。

Windows就是使用BOM来标记文本文件的编码方式的。

原来BOM是在文件的开始加了几个字节作为标记。有了这个标记,一些协议和系统才能识别。

ok,说了这么多背景,那么如何解决这个问题呢?

如何使用BOM头

BOM头的删除

对UTF-16, Python将BOM解码为空字串。然而对UTF-8, BOM被解码为一个字符,如例:

简单的做法是在文件读入时使用

即可,具体可以参见[http://docs.python.org/library/codecs.html#module-encodings.utf_8_sig|http://docs.python.org/library/codecs.html#module-encodings.utf_8_sig]

或者:

BOM头的添加

参考 http://www.cnblogs.com/DDark/archive/2011/11/28/2266085.html

python下的编码检测——chardet

在处理字符串时,常常会遇到不知道字符串是何种编码,如果不知道字符串的编码就不能将字符串转换成需要的编码。面对多种不同编码的输入方式,是否会有一种有效的编码方式?chardet是一个非常优秀的编码识别模块。

chardet 是python的第三方库,需要下载和安装。现在 pip 已经可以很好的支持这个版本的下载了,建议使用pip 安装,关于pip 的安装部分,可以参考Windows下python的包管理器pip安装
在安装完chardet模块,我就可以使用它了,来看一段示例代码。
运行结果表示有99%的概率认为这段代码是GB2312编码方式。
另外一个相对高级的应用。

应用背景,如果要对一个大文件进行编码识别,使用这种高级的方法,可以只读一部,去判别编码方式从而提高检测速度。

参考 http://blog.csdn.net/aqwd2008/article/details/7506007

Windows下python的包管理器pip安装

做python开发,要用到第三方包,关于MAC下面如何安装Pip ,可以参考前面的 Mac OS 10.9 下python安装easy_install pip 现在我们看看在Windows下面的操作,打开 Pip的官方安装指南https://pip.pypa.io/en/latest/installing.html

Installation

Python & OS Support

pip works with CPython versions 2.6, 2.7, 3.1, 3.2, 3.3, 3.4 and also pypy.

pip works on Unix/Linux, OS X, and Windows.

Note

Python 2.5 was supported through v1.3.1, and Python 2.4 was supported through v1.1.

Install pip

To install or upgrade pip, securely download get-pip.py.(如果官网下载不下来,可以点这个链接在本网站下载

Then run the following (which may require administrator access):

If setuptools (or distribute) is not already installed, get-pip.py will install setuptools for you. [2]

To upgrade an existing setuptools (or distribute), run pip install -U setuptools. [3]

To enable the use of pip from the command line, ensure the Scripts subdirectory of your Python installation is available on the system PATH. (This is not done automatically.)

Additionally, get-pip.py supports using the pip install options and the general options. Below are some examples:

Install from local copies of pip and setuptools:

Install to the user site [4]:

Install behind a proxy:

Upgrade pip

On Linux or OS X:

On Windows [5]:

Using Package Managers

On Linux, pip will generally be available for the system install of python using the system package manager, although often the latest version will be unavailable.

On Debian and Ubuntu:

On Fedora:

RicheditCtrl 控件在不同语言环境的操作系统上可能出现的乱码问题

由于工作上需要,把软件移植到英文版的os上(软件已是unicode版本的),发现RicheditCtrl
控件上显示的字体(本来内容应该显示为中文)乱码了。

发生乱码的具体代码:

查找原因:可能是控件不了解字符串已经是unicode代码,所以控件根据locale 的code page来硬性将代码转换为unicode显示,所以出现乱码。

解决方法:

The code page used to translate the text to Unicode. If codepage is 1200 (Unicode code page), no translation is done. If codepage is CP_ACP, the system code page is used.
参考 http://www.cppblog.com/jeffrey78/articles/2214.html

Ubuntu 14使用Nexus2.x为Maven3.x搭建私服构件仓库

一、下载与安装Nexus

想为Maven搭建私服,我们可以选择使用Nexus工具,目前已知提供war包的版本为2.2.0,其下载地址为:http://www.sonatype.org/nexus/go

39e36edc-a0d2-3b49-afd8-d0e4a175eb5a

这里我们下载War包,直接部署到Tomcat 7 下面,Ubuntu 下面是 /var/lib/tomcat7/webapps。
接下来我们可以在浏览器中输入http://127.0.0.1:8080/nexus/查看Nexus是否成功.

如果提示错误,则到 /var/log/tomcat7/localhost.YYYY-MM-DD.log 下面查看日志,有可能报告 /usr/share/tomcat7/sonatype-work 权限问题,则说明Nexus 没有权限创建这个目录,因此我们需要手工创建这个目录,然后赋予这个目录 777权限,然后重启 Tomcat.

目前最新的版本Nexus 2.12.0-01,(Nexus OSS官网下载2.x的Tomcat/WAR版本) 。3.x版本已经不提供WAR包下载了,只能是使用Jetty的版本了。

Ubuntu下面的操作如下:

修改bin/jsw/conf/wrapper.conf,设置wrapper.java.command=jdk所在目录/bin/java

修改后的内容如下:

设置目录的权限

启动服务

这种安装模式下,访问的链接地址为http://localhost:8081/nexus

注意,首次启动的耗时时间很长,貌似需要建立数据库等,需要耐心等待几分钟。

如果成功,则出现下面的界面

39e36edc-a0d2-3b49-afd8-d0e4a175eb5a

通过上图我们可以发现我们已经成功的启动了Nexus,那么接下来要做的事情就更有意思了,在后续章节中笔者会陆续讲到应该如何使用Nexus工具来配置和管理咱们的私服仓库。

二、仓库类型

在上一章节中,笔者讲解了如何下载与安装Nexus工具。那么本章节咱么来看看如何使用Nexus工具配置和管理私服仓库。当然在使用Nexus之前你是需要登录的,缺省账号密码为:

account:admin;

password:admin123;

当成功登录后,你可以单击 Repositories属性看到如下页面:
d5600d88-1881-37aa-a4e3-d4e7c12bbf29

由于admin这个账号是属于Administrator权限的,你也可以通过单击Security属性进行账户的配置:

9a6d675e-b13b-327d-b1cb-3c05132db8a7

Nexus的仓库类型一共有4种,每一种仓库类型均对应有不同的操作方式:

1、group: 仓库组;

2、hosted:宿主;

3、proxy:代理;

4、virtual:虚拟;

来吧,咱们先谈谈仓库组这个概念,一个仓库组类似一个仓库集合,它和仓库之间是一对多的关系,也就是说一个仓库组可以允许包含多个仓库,Nexus仓库用例图如下:

96308ff7-be2f-38a3-bc0b-63c8056b1999

在咱们弄明白仓库组的作用后,咱们接着来看宿主仓库是干什么的。其实所谓宿主仓库可以理解为自定义仓库,用于存放一些在中央仓库无法下载的构件,比如自定义构件你可以手动将自定义构件上传至hosted中

代理仓库起到的作用是代理作用,假设本地仓库向私服进行请求时,首先会去私服仓库的本地路径中寻找构件,如果没有找到则会从中央仓库进行下载。

虚拟仓库省略...

 三、使用Nexus管理私服仓库

在了解Nexus的4种仓库类型后,咱们接下来要做的事情就是使用Nexus工具来管理咱们的私服仓库。先来看看Nexus为我们提供的一些缺省仓库:

ac73186e-3406-3004-8849-fab7ad41f8d9从上图我们可以看出Nexus缺省为我们定义了1个仓库组,7个仓库。当中最主要的几个仓库为:

9461f779-b4b9-3b03-b616-5d1ad4c8f494

3rd party(宿主仓库):用于存放一些在中央仓库无法下载的构件仓库;

Apache Snapshots(代理仓库):代理ApacheMaven仓库快照版本的构件仓库;

Central(代理仓库):代理Maven中央仓库中发布版本构件的仓库;

当然你可以根据项目需要新建仓库组及仓库,但在建立这些私有的仓库之前,咱们还是先来看看如何使用Nexus为咱们提供的缺省构件仓库(其实很多时候你真没必要去新建仓库)。

选择Public Repositories分组,单击configuration选项,你可以为仓库组添加对应的仓库:

b07178d7-64b8-3a7f-8b99-93451450ea92

单击Save按钮保存即可配置完成。这里有一点需要提醒大家的是,仓库的添加顺序直接决定了构件的下载顺序,换句话来说我们应该把需要从中央仓库或者其他远程仓库下载构件的代理仓库添加在最后

当咱们成功将指定的仓库集合添加进仓库组后,接下来我们来为3rd party(宿主仓库)上传自定义构件,所谓自定义构件指的是无法从Maven的中央仓库进行下载的构建。

笔者在此选用的是最简单方便的手动上传构件(当然上传构件至宿主仓库还有一些方式,但笔者还是侧重于最简便的方式)。

单击3rd party(宿主仓库)的Artifact Upload选项,我们首先来上传一个基于Maven项目的自定义构件:773c6508-1474-3853-ba4e-217198d96ee5

最后别忘记了添加构件:

c7016c60-68b4-38b9-afd4-e14fe4730fd4

如果你的构件不是基于Maven的呢?那么你可以选择GAV Parameters属性:61fe1457-f7e3-3452-a30b-886879c7d62b

接下来,需要配置 Maven 来连接到似有仓库,如果需要全局配置,则配置地址为 ~\.m2\setting.xml,如果需要根据工程配置,则需要跟pom.xml在同一个目录下面即可,文件存在则修改,不存在则创建,内容如下

参考 http://gao-xianglong.iteye.com/blog/1735536

Ubuntu下文件关联

需要涉及到以下几个目录和文件
~/.local/share/applications
/etc/gnome/defaults.list
/usr/share/applications
/usr/share/applications/mimeinfo.cache
~/.local/share/applications/mimeinfo.cache
去这几个目录看一下,就会发现很多以 desktop 为后缀的文件。
这些文件是多功能的,第一,它们是组成GNMOE的“开始”菜单的一部分,即“开始”
菜单里的一些应用程序项,在这里都能找到。你可以运行 alacarte , 这里会
列出整个菜单的结构,你可以编辑它,但是很多项你没法删除,因为没有权限,
你试着用root权限去运行 alacarte ,抱歉,你还是没有权限删除,要删除它们,
只有在/usr/share/applications下面找到对应的文件,直接删除这个文件即可。
从总体上讲
/etc/gnome/defaults.list 保存了全局的打开方式 
~/.local/share/applications/defaults.list 保存了个人的打开方式 
当两着不一致是,优先采用局部的个人设置。
~/.local/share/applications 
/usr/share/applications 
这两个分别是局部的desktop项和全局的desktop项 
/usr/share/applications/mimeinfo.cache
~/.local/share/applications/mimeinfo.cache
这两个分别是全局的和局部的打开方式缓存
先看一下/etc/gnome/defaults.list的结构

不难发现
是这样的一种形式
程序的类型/文件类型=打开这个文件的项[;项2]...[;项n]
候选打开方式可以有好几种
中间用;隔开,不留其余字符
要修改一个文件的打开方式,需要先确定这个文件的类型
以纯文本文件为例 类型是plain 打开方式默认为vim.desktop
候选的是firefox.desktop
text/plain=vim.desktop;firefox.desktop
可以直接编辑
~/.local/share/applications/defaults.list
/etc/gnome/defaults.list
编辑完之后,手工修改
/usr/share/applications/mimeinfo.cache
~/.local/share/applications/mimeinfo.cache
这两个cache文件。
这样就立即生效了
下面看一下desktop文件的结构
[Desktop Entry]
Encoding=UTF-8 //字符编码
Name=vim  //现实的名字
MimeType=text/plain; //类型
Exec=vim %f //运行的程序 %f表示一个参数
Type=Application //类型
Terminal=true //是否使用终端
NoDisplay=true //是否显示在gnome菜单里
知道这些
就可以很方便的定制“开始”菜单和文件的打开方式了

Debugging NDIS Drivers

Windows Platform Design Notes

Design Information for the Microsoft® Windows® Family of Operating Systems

Debugging NDIS Drivers

Abstract

This paper provides information about debugging Network Driver Interface Specification (NDIS) drivers for the Microsoft® Windows® family of operating systems. It provides guidelines for the NDIS driver developer to identify commonly encountered issues in network drivers and specifies best practices that will help the driver developer avoid network driver issues in the first place. This paper also provides information on how to use Ndiskd.dll, the NDIS kernel debugger extension, to gather information about the state of NDIS and the NDIS drivers.

Contents

Introduction. 3

NDIS Overview.. 3

Using Ndiskd.dll to Debug NDIS Drivers. 4

Debugger Extensions. 6

NDIS Tracing. 9

NDIS Bug Checks. 10

PnP Overview.. 11

Debugging a Miniport Initialization Problem.. 12

Debugging the Failure of a Miniport to Halt13

Debugging Power Management Issues. 14

Debugging Interrupt Storms. 15

MiniportReset Overview.. 16

Best Practices for Developing Miniport Drivers. 16

Tools – Using NDISTest and Driver Verifier16

Using Debug Messages. 16

Tracking Spin Locks. 16

Best Practices for Developing Intermediate Drivers. 17

Common Intermediate Driver Issues. 17

Best Practices for Developing Protocol Drivers. 18

Call to Action and Resources. 18

This is a preliminary document and may be changed substantially prior to final commercial release of the software described herein.

The information contained in this document represents the current view of Microsoft Corporation on the issues discussed as of the date of publication. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information presented after the date of publication.

This White Paper is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS DOCUMENT.

Complying with all applicable copyright laws is the responsibility of the user. Without limiting the rights under copyright, no part of this document may be reproduced, stored in or introduced into a retrieval system, or transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or otherwise), or for any purpose, without the express written permission of Microsoft Corporation.

Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property.

Unless otherwise noted, the example companies, organizations, products, domain names, e-mail addresses, logos, people, places and events depicted herein are fictitious, and no association with any real company, organization, product, domain name, e-mail address, logo, person, place or event is intended or should be inferred.

® 2003 Microsoft Corporation. All rights reserved.

Microsoft, Windows, and Windows Server are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries.

The names of actual companies and products mentioned herein may be the trademarks of their respective owners.

Introduction

This paper provides information about debugging NDIS drivers for the Microsoft® Windows® family of operating systems. It also provides coding practices that driver developers can use to avoid common problems encountered by NDIS drivers such as initialization failures in NDIS miniports, NDIS Intermediate drivers whose miniports do not get halted, and other common issues reported to the NDIS team at Microsoft. The paper discusses:

  • Ndiskd.dll—NDIS kernel debugger extensions
  • NDIS tracing
  • PnP overview
  • Power Management overview
  • NDIS intermediate drivers
  • NDIS protocol drivers

Note: The information presented in this paper is applicable to Microsoft Windows Server™ 2003 driver development. Most of the information also applies to Microsoft Windows XP and Microsoft Windows 2000.

NDIS Overview

This paper assumes that you are familiar with the basic NDIS model. In addition to the miniports and protocols that have been discussed in the Microsoft Windows Driver Development Kit (DDK), this paper introduces the MOpen structure that represents a binding between a protocol and a miniport. The model, including the MOpen structure, appears in figure 1.

NDIS_diagram_including_the_MOpen_structureFigure 1: NDIS diagram including the MOpen structure

Using Ndiskd.dll to Debug NDIS Drivers

Developers and testers at Microsoft Corporation use Ndiskd.dll to quickly analyze potential network driver issues. Ndiskd.dll is a part of the Microsoft Debugging Tools package for kernel-mode debugging. Ndiskd.dll runs on both WinDBG.exe and Kd.exe, and it provides basic and detailed information about a miniport driver and the protocol drivers that are bound to it.

The most commonly used Ndiskd.dll commands are !miniports and !miniport <MiniportAdapterHandle>. Use the !miniports command to print all of the NDIS miniports that are present in the system. Use the !miniport <MiniportAdapterHandle> command to print detailed information about a miniport adapter, including the protocols it is bound to and the miniport’s PnP and power management states.

The following example shows how to get detailed information about a particular protocol that is bound to the Sample Ethernet Driver miniport. The Sample Ethernet Driver is a real NDIS miniport driver that has been given a fictitious name.

To print detailed information about the Sample Ethernet Driver, use the !miniportcommand. The pointer in bold in the preceding example is the argument to !miniport.

Use the !mopen command to print detailed information about an Mopen structure, or binding, between the Sample Ethernet Driver and a protocol. Use the pointers in bold from the preceding example as arguments for the !mopen command.

To print information about the protocol structures use the !protocol command. Use the pointer in bold from the preceding example as the argument to the !protocol command.

The preceding example shows how to use the list of miniport drivers in the system to get detailed information about the protocols that are bound to a miniport adapter. The example printed four sets of information:

  • Detailed information about each NDIS miniport adapter in the system.
  • Specific information about the Sample Ethernet Driver.
  • Detailed information about each of the Mopen structures, or bindings, on the Sample Ethernet Driver miniport.
  • Detailed information about the NdisUio protocol.

Note: For detailed information about Ndiskd.dll, see the Help file provided with the Microsoft Debugging Tools, and the Microsoft Windows Driver Development Kit (DDK).

Debugger Extensions

Three useful debugger extensions exist that are not well known:

  • !pkt
  • !findpacket -p
  • !stacks

Ndiskd.dll includes the !pkt and !findpacket commands. The !stacks command is part of the Microsoft Debugging Tools package and is not included in Ndiskd.dll.

!pkt Command

The !pkt command prints out detailed information about an NDIS_PACKET structure. You can specify a verbosity level to control the amount of information that the debugger prints, as shown in the following code.

To print every NDIS_BUFFER structure in an NDIS_PACKET structure, use a verbosity level of 4:

The preceding example prints every NDIS_BUFFER structure in a particular NDIS_PACKET structure, as well as the Out-Of-Band(OOB) information in the NDIS_PACKET structure.

!findpacket p Command

The !findpacket -p command finds all the packets that are allocated from a particular packet pool and that are currently in use by the miniport driver. Intermediate (IM) driver developers can use the findpacket -p command to list all of the packets that are allocated by the IM driver and indicated up to the protocols.

The following example shows how to locate all of the packets that are currently allocated in a packet pool. You need to pass the packet pool’s PoolHandle, that was returned to the NDIS driver when it called the NdisAllocatePacketPoolEx function, as the argument to the !findpacket -p command, as shown below.

!stacks Command

Use the !stacks command to find hung threads and to debug other difficult problems. This extension is present in the Debugger package but is not a part of ndiskd.dll.

You can specify a character string as an argument to the !stacks command. The debugger prints all the threads that contain the character string in their stacks. For example, the command !stacks 2 ndis! causes the debugger to print every thread that contains the “ndis!” string in its stack.

The threads printed by the debugger can provide important clues that will help you solve the problem you are investigating. For example, the output in the following code was taken from an IM driver that was not completing any requests to send packets. When the miniport adapter was disabled, the underlying miniport adapter was never halted as TCP/IP waited for the IM driver to complete the sends. The output, which is the result of the !stacks 2 ndis! command, contains two threads: one that shows TCP/IP waiting for outstanding sends to complete, and another that is an NDIS thread reserved for system use.

The preceding example shows the benefit of running the !stacks 2 ndis! command, which provides useful clues about the current state of the computer. In the example, you can see that TCP/IP is waiting for an event. It is reasonable to assume that it is waiting for outstanding sends. Later in this paper, you will see how this assumption can be verified.

The second thread printed in the preceding example is reserved for system use.

Use the !stacks 2 <miniport driver name> command to print all the threads with the miniport driver’s name in their stacks.

NDIS Tracing

NDIS has debug messages built into its checked version. By default, these are not printed in the debugger and need to be turned on. Use NDIS tracing to analyze problems that are not in the data path, such as PnP and power-management problems. NDIS tracing works on both free and checked builds of the operating system.

The following example demonstrates how to turn on the NDIS tracing feature in the REQUEST code path at the INFO level within NDIS. There are four levels of debug messages available to the developer: Info, Warn, Err and Fatal. The Info level is the most verbose, and the Fatal level is the least verbose. (The Log level has not been implemented.)

The Dbglevel and Dbgsystems settings are toggle settings. To turn off the debug print feature for the REQUEST and BIND code paths, you must re-enter the previous command, as shown here:

The preceding example shows how you can set and reset the verbosity and component values, which control the level of debugging information that NDIS prints in the debugger.

NDIS Bug Checks

The system performs a bug check when it detects an error caused by an NDIS miniport driver. The bug check is performed as soon as an error is detected. If the system did not stop, these errors would appear later, making it difficult to pinpoint the cause of the problem at that stage.

The bug checks that are caused by an NDIS miniport driver use a special bug check code. On Windows XP and Windows 2000, the bug check code is BUGCODE_ID_DRIVER. On Windows Server 2003, the bug check code is BUGCODE_NDIS_DRIVER. If a debugger is connected to the system being tested, a sentence describing the bug check is printed in the debugger. The !analyze –v command provides detailed information on the bug check.

Examples of NDIS miniport driver problems that cause the system to perform a bug check include the following:

  • Before the ownership of a receive packet, that the miniport driver indicated by calling the NdisMIndicateReceivePacket function, is transferred back to the miniport driver, the driver indicates the packet in another call to NdisMIndicateReceivePacket.
  • The miniport driver frees shared memory that it has not allocated.
  • The miniport driver unloads without deregistering an interrupt that it previously registered.

Note: For more information about bug check codes, see the Debugger.chm help file in the Microsoft Debugging Tools package.

PnP Overview

NDIS implements the following Plug and Play (PnP) functionality on behalf of the miniport:

  • NDIS intercepts all the PnP driver and device IRPs that are sent to the miniport driver.
  • NDIS and the driver together comprise the functional device object (FDO) of the miniport adapter.
  • NDIS implements the AddDevice routine on behalf of the minport driver. In response to the StartDevice IRP, NDIS calls the MiniportInitialize function handler of the miniport driver.
  • NDIS propagates the Remove/Stop IRP to the miniport driver’s MiniportHalt function. Before calling this function, NDIS unbinds all the protocols bound to that miniport.

The !ndiskd.miniport command prints information that is useful for debugging PnP problems, as shown in the following example.

The !miniport extension prints a lot of useful information. The items that the previous example prints include the following:

  • The PnP state of the miniport adapter.
  • The physical device object (PDO) and the FDO of the miniport adapter.
  • The protocols that are bound to the miniport adapter.
  • The hardware resources that are assigned to the miniport adapter.

Debugging a Miniport Initialization Problem

Miniport adapters can fail to initialize for a variety of reasons. If the problem is reproducible, the best way to proceed is to turn on NDIS tracing and reproduce the problem. The debug messages printed in the debugger makes it easy to identify the point of failure.

To debug a miniport initialization problem:

  1. Turn on NDIS tracing.
  2. Look for the statement specifying the failure code that the MiniportInitialize function handler returns.
  3. Using the failure code as a starting point, find the last NDIS function that the miniport called before it entered the failure code path.
  4. Inspect the source code of the miniport driver to find the cause of the fault.

The following example contains the debugging messages that are printed during the initialization of a miniport adapter.

The preceding example shows a miniport adapter failing its initialization routine. In the beginning of the example, NDIS gets called at its AddDevice routine for the miniport, followed by a StartDevice IRP. As part of the IRP, NDIS calls the MiniportInitialize function handler, which fails because of an error that occurred after it successfully called the NdisMRegisterIoPortRange function. You can use this information as the starting point for debugging the initialization problem. NDIS debug messages also tell you if the NDIS API failed and possibly why it failed.

Debugging the Failure of a Miniport to Halt

If NDIS does not call a miniport driver’s MiniportHalt function when the miniport adapter is disabled through the user interface or an automated test, it is usually because an operation that the miniport driver must complete before being halted has not completed. For example, NDIS will not halt a miniport adapter until the driver finishes sending all the packets that were sent to it for transmission.

To debug the failure of a miniport to halt:

  1. Run the !stacks 2 ndis! command in the debugger to print all the threads that contain the “ndis!” string in their stacks.
  2. Inspect the threads to see if they offer any clues. For example, a thread that shows TCP/IP waiting implies that the protocol is waiting for the miniport driver to complete send operations.
  3. To find the number of outstanding requests to send packets in the miniport, print all of the Mopen structureson the miniport as explained earlier in this paper. If the miniport driver is not completing packets back to the protocol, the Referencesvalue never returns to one. Calling the NdisCloseAdapter function also decreases this value by one.
  4. Investigate the miniport driver to see why the miniport is not completing the packets. The miniport driver calls the NdisMSendComplete function to complete such send operations.

The following example shows an MOpen structure between the NDISUIO protocol and the Sample Ethernet Driver miniport.

The preceding example shows an Mopen structure between the NDISUIO protocol and the Sample Ethernet Driver. NDIS has called the protocol’s ProtocolUnbindAdapter handler.The protocol has called the NdisCloseAdapter function. NDIS will not call the protocol’s CloseAdapterComplete handler until the number of references reaches zero. The references are caused by outstanding send commands in the miniport.

Debugging Power Management Issues

As the device power policy owner of the miniport, NDIS is responsible for querying the bus driver, the miniport driver, and the system settings before deciding on the power management policy for the miniport adapter.

To find the values returned by the bus driver and the miniport driver, turn on NDIS tracing or look at the output of the !miniport command:

In the preceding example, NDIS sets the DISABLE_WAKE_UP flag, because the user has not enabled Wake-On-LAN (WOL) for this miniport adapter. To debug a WOL problem, you need to inspect the power management values returned by the system, the bus driver, and the miniport to determine which of the three entities is disabling WOL. These values are all displayed in the output of the !miniport command.

Debugging Interrupt Storms

Interrupt storms occur when either a miniport driver fails to disable device interrupts or the device continues to assert an interrupt after that interrupt has been disabled. In either case, the computer is not usable until the device stops asserting interrupts.

To diagnose an interrupt storm problem:

  1. Set a breakpoint on the MiniportISR function.
  2. If MiniportISR returns TRUE, set a breakpoint on the MiniportDpc function. MiniportISR should not return TRUE until the MiniportDpc functionenables interrupts.
  3. Investigate why the device is asserting an interrupt before the DPC has completed.

MiniportReset Overview

When a miniport driver calls the NdisMResetComplete function, NDIS completes all outstanding requests on behalf of the driver. If that driver is a serialized driver, NDIS also returns all the send packets that NDIS has queued for the driver to the appropriate protocol drivers.

Best Practices for Developing Miniport Drivers

The following practices are followed by developers at Microsoft Corporation when developing NDIS drivers:

  • Running tools such as NDISTest and Driver Verifier.
  • Using debug messages.
  • Tracking Spin Locks.

Tools – Using NDISTest and Driver Verifier

NDISTest and Verifier.exe are good tools to use when developing NDIS drivers. NDISTest aids and verifies the completeness of a miniport driver. You should use it on both miniports and IM drivers. NDISTest cannot test protocols. Use Driver Verifier to ensure that common errors are easily found and rectified early in the development cycle.

Use Driver Verifier from the beginning of the development effort. Use NDISTest to test the functional completeness and robustness of the driver. You can run an individual test from the test suite to test specific features of the NDIS driver.

Using Debug Messages

The __LINE__ compiler directive is a useful tool. The compiler replaces each __LINE__ directive with the actual line number in the file, which is useful for logging or printing debugging messages.

Tracking Spin Locks

You can enhance a deserialized driver to track the acquisition and release of spin locks by recording each file and line number that acquired a spin lock. This record is cleared just before releasing the spin lock.

At the beginning of each .c file, include a #define statement that uniquely identifies the file, as shown in the following code. Be sure that the defined value is larger than the number of lines that a file could contain, because the line number and the file number will be combined into a single unsigned integer.

Define the following structures and macros in a header file of the driver:

The preceding structure and two macros enable you to quickly find the line of code that last acquired the spin lock. To verify that no spin-lock issues exist in the code, run Driver Verifier with the Deadlock Detection option turned on. Each acquisition of a spin lock will be tested to make sure that it occurred in the right order with respect to all the other spin locks in your driver.

Best Practices for Developing Intermediate Drivers

An NDIS IM driver is complex, because any of the entry points in the driver’s protocol module or miniport module can be called regardless of the state of the other module.

The IM driver must ensure that a notification, such as a send or receive command to one of its modules, does not result in an incorrect action from its other module. For example, when NDIS requests that an IM driver’s miniport module should send a packet, the driver must then determine whether the protocol module can propagate the packet down or if the packet needs to fail.

You should maintain a reference count on all outstanding actions that the IM driver will be called back for—actions such as send commands and requests that the driver initiates to the miniport below it. This reference count should be synchronized with the unbind code in the protocol. The IM miniport should also maintain a reference count of the number of outstanding receive commands that the IM driver has indicated. This count must be synchronized with the PnP code path in the IM miniport driver, to ensure that no receive commands occur after the IM miniport adapter has been halted.

Common Intermediate Driver Issues

When developing an IM driver, you might encounter the problem of TCP/IP not sending packets to the IM driver for transmission. Common causes of this problem include the following:

  • The IM driver is reporting an invalid 802.3 physical (MAC) address.
  • The IM driver is indicating corrupted packets to TCP/IP.
  • The IM driver’s MiniportTransferData function handler is returning corrupted packets.

You should run NDISTest on the IM driver to solve such problems.

Another problem is that outstanding send and request commands in the IM miniport module can prevent NDIS from calling an IM driver’s MiniportHalt routine after the driver has called the NdisIMDeInitializeDeviceInstance function. In this situation, the IM driver could have passed such a packet to the miniport adapter below it, or queued the packet internally. The Mopen structure can determine whether any packets were passed to the underlying miniport.

Best Practices for Developing Protocol Drivers

The problems that commonly occur with protocol drivers are similar to those that occur with IM drivers. As described earlier, it is important to synchronize the protocol driver’s PnP code path with the driver’s send code path.

Use the appropriate I/O Control (IOCTL) codes when designing the protocol driver’s IOCTL interface. IOCTLs should specify the METHOD_BUFFERED option as documented in the DDK and have the appropriate read or write privilege set in the IOCTL code. If an IOCTL is going be used only when an Administrator is logged on, the protocol driver should create a device object by calling the IoCreateDeviceSecure routine.

Call to Action and Resources

Call to Action:

  • For driver developers:
  • Run NDISTest and Verifier on NDIS drivers during development. These tools verify functional completeness and find common errors in a reproducible manner.
  • Build kernel debugger extensions to quickly extract useful information from the driver’s data structures.
  • Build diagnostic information into your NDIS driver to quickly identify issues.
  • Post questions on the public Microsoft device driver newsgroup. It is an excellent forum for both novice and expert developers.

For questions about debugging and developing NDIS drivers, post questions on the public Microsoft device driver newsgroup.

For specific questions about this paper, send e-mail to ndis6fb@microsoft.com.

Resources:

Microsoft Hardware and Driver Developer Information

http://www.microsoft.com/hwdev/

Microsoft Windows Driver Development Kit (DDK)

http://www.microsoft.com/ddk/

Microsoft Debugging Tools

http://www.microsoft.com/ddk/debugging/default.asp

Microsoft’s public device driver newsgroup

microsoft.public.development.device.drivers

WD My Cloud OOM-Killer 杀死sshd服务导致无响应问题解决

WD My Cloud 的内存只有256M,在安装一系列应用之后,往往会导致内存不足,尤其是磁盘对拷的时候,很大的文件,往往会导致 Linux 内核的 OOM-Killer动作,导致 sshd ,Apache 等的服务被杀死,此时系统的指示灯是正常的,但是网络响应全无,只能强制断电。

先简单讲一下OOM-Killer的原理

OOM-killer:Out-of-Memory (OOM) Killer是一种保护机制,用于当内存严重不足时,为了系统的继续运转,内核迫不得已挑选一个进程,将其杀死,以释放内存,缓解内存不足的问题。
可以看出这种方式对进程的保护是有限的,不能完全的保护进程的运行。

OOM Killer的关闭与激活方式:

在实际运营场景中,我们经常出现ssh连接不上服务器,但ping却是通的情况,这个时候很有可能是内存不够linux启动了oom-killer,系统根据一定的分数和机制来决定
随机杀掉一些程序释放物理内存(特别是我们后台需要大量共享内存而且用了mlock的程序),而sshd进程很可能就是被选中杀掉的进程,因此导致通过ssh登录不上。
这个时候基本上swap也被耗尽, 所有能释放内存的机制内核都已经尝试了。

而ping能够通,主要是因为ping其实是内核协议栈就直接回包了,不会走到用户态,所以还能证明机器还是活着的。

对于每个进程都有一个oom_score的属性/proc/PID/oom_score
oom- killer 会杀死oom_score较大的进程,当oom_score为0时禁止内核杀死该进程。

还有一个/proc/PID/oom_score_adj
一般来说,oom_adj的值越大,该进程被系统选中终止的可能就越高,当oom_adj=-17时,oom_score将变为0。
(要对某个进程进行OOM保护的话就直接向“/proc/pid/oom_adj”中写入“-17”即可。)

所以可以通过命令

来防止重要的进程被oom_killer杀死。

例如可以把sshd进程的oom_adj改为0 ,包括自己连接上的那个终端进程,这样你还可以执行一些运维工作。

既然了解到这些,那么操作方式就很简单了。

为了防止SSHD被杀死,可以在命令行中执行如下命令

为保万无一失,利用Linux的计划任务cron来做一下定时检查。

里面内容如下

表示每10分钟执行一次进程存在检查。

使用USB3.0调试Windows 8

Windows 8,成也,败也?众说纷纭。但无论如何,我很喜欢它所作出的如下改变:

- 开发语言回归C++

- 旧的Win32与新的WinRT两套API的“双头”模式

- 重视内核调试,引入两种新的连接方式,并将内核调试支持纳入徽标测试

当然,也有不喜欢的地方,首当其冲的就是新的启动选项界面——居然是一个应用程序,需要内核先起来才能运行,如果内核起不来,那么这个启动选项根本没办法出来,想靠它抢救起不来的系统,基本没指望,真是十足“脑残”的设计。

真的不愿意看Windows走下坡路,还是回过来说它的优点吧,今天就聊一下新的USB3调试。

主机端要求:

H.1 支持USB 3的端口;

H.2新版本的WinDBG,6.2.9200或者更高;

H.3 Windows 8系统。

前两项是必须的,没得商量,第3项按理说Windows 7也可能成功,但是官方的说法要求Windows 8。笔者曾经在Windows 7上试验过,有USB 3硬件,USB 3的驱动和USB2DBG驱动也都安装成功了,但是还是没能建立起调试连接,原因应该是和总线驱动有关,内建的USB 3驱动是从Windows 8才开始的。

目标机的要求:

T.1 Windows 8系统;

T.2 有可用的USB 3端口,下面详细描述。

T.3 USB 3的控制器是支持调试的,与此前的USB 2调试类似,调试痛信是一种特殊的简单通信,要求USB 3控制器特别支持才行,但与此前USB 2的控制器只有0号口支持调试不同,USB 3的控制器的所有3.0口都是支持调试的,因此这个要求一般都满足,可以使用USBView工具检查是否支持Debug,如图1所示;

T.4 启用内核调试。

usbview

图1 UsbView

USB 3的端口有很多种,PC上常见的有A和B两种,A与以前的USB 1.0/2.0端口看起来很像,物理属性是兼容的,每部的信号线有不同,识别是否是USB 3端口的简单方法就是看是否是有SS标记,SS代表Super Speed,如果标记是SS,那么就是USB 3端口。

USB 3的B端口是长相很特别,一道沟槽/凸起将端口分为不对称的两个部分。图2照片中的线是把B口转成A口的,通过这个图,大家就可以知道A、B两种口的长相了。

usb3_b2a

图2 USB 3的B-A转接电缆(和黑布林在一起,压缩算法把bitrate似乎都分在布林身上了,线不大清楚)

接下来该说电缆了,与USB 2调试所需的中间带有设备的特别电缆不同,USB 3调试需要的是一条真正的线。哪里能买到这种线呢?国外有公司卖。经过一番调查和尝试,其实也可以从国内买,然后略微加工一下就可以了。这种方法是由一位聪明的同事试验成功的,我亲自尝试了一下,确实简单有效。

先从淘宝买一根USB 3的A对A连线,有时也称公对公连线,很便宜。这根线需要加工一下才可以支持调试,加工的方法是选取线的某个位置,剥开外皮,然后把其中的红绿白三根线剪断,然后包上就可以了。USB 3电缆的线是有固定颜色的,如图3所示,

usb3_cable

图3 花花绿绿的USB 3线缆

其中SDP是Shielded Differential Pair的缩写,即屏蔽起来的差分信号线,是USB 3.0的数据线,UTP是Unshielded Twisted Pair的缩写,即未屏蔽的双绞线,是USB1/2使用的数据线,所谓的D+,D-。要做的加工其实就是把2.0的三根弦剪断。剥开后,很容易找到红绿白三根,胆大心细,下剪子吧:-)。

usb3_a2a

图4,看准下剪子 (照片不大清楚,剪错了责任自负哦)

线做好后,用它来接主机和目标机。

然后需要在目标机上启用调试。打开一个有管理员权限的控制台窗口,执行如下命令:

设置好后需要重启。

最后再说一下主机端,安装好新版本的WinDBG后,以管理员身份启动运行,File  > Kernel Debugging,选择USB ,然后指定名称(上面bcdedit里设置的名字)。第一次使用的话,WinDBG会自动安装驱动,这也是要以管理员启动的原因。需要说明的是,在主机端,USB 2.0调试和3.0调试使用的是一个驱动Usb2DBG,不必怀疑。

好了,主机端就绪后,按Ctrl + Break,目标机应声断下,设置符号,开始开Windows 8的代码或者找Bug吧!

转自 http://advdbg.org/blogs/advdbg_system/articles/5954.aspx

VS2012编译出来的程序,在XP上运行,出现“.exe 不是有效的 win32 应用程序” “not a valid win32 application”

升级vs2010到vs2012,突然发现build出来的应用程序无法运行,提示“不是有效的 win32 应用程序” or “not a valid win32 application”。

参考CSDN论坛中的方法,找到下面这篇文章:

http://blogs.msdn.com/b/vsnetsetup/archive/2012/10/16/setup-exe-is-not-a-valid-win32-application.aspx

You would receive the below error message while running a ClickOnce bootstrapper created using Visual Studio 2012 on Windows XP systems.

 0336.Untitled1.png-550x0

Clickonce bootstrapper engine (setup.exe) that was shipped with Visual Studio 2012 is NOT compatible with any OS below Windows Vista.  So, the above error message is expected and by design. The reason for this behavior is because the bootstrapper is compiled using the VC compiler and the Dev11 VC compiler does not support Windows XP.  

So the workaround is to install all the prerequisites manually and launch the ClickOnce application directly from deployment manifest file (.application). Another workaround would be to create a sample ClickOnce application using Visual Studio 2010 OR Visual Studio 2008 with the same name as mentioned in Visual Studio 2012 and publish it. From the published location take the setup.exe bootstrapper and replace the existing setup.exe bootstrapper created using Visual Studio 2012

Microsoft VC development team has done work to make VC compilers work on Windows XP in Visual Studio 2012 Update 1 CTP 3 http://www.microsoft.com/en-us/download/details.aspx?id=34818 This Visual Studio 2012 Update 1 CTP 3 patch provides an opportunity to users in building VS2012 C++ project for Win XP OS. For the users who want to develop their applications using Dev11 VC compiler (v110) for Windows XP OS, would need to install Visual Studio 2012 Update 1 CTP 3 patch.

 8535.Untitled.png-550x0

文章提示,dev11 VC complier 已经不在支持XP,如果想要支持XP系统,需要更新至 VS2012 Update1,同时,在

Properties -> Configuration Properties -> General -> PlatForm ToolSet

选择

Visual Studio 2012 - windows XP (v110_xp)

这样compiler生成的exe文件方可在XP系统上运行。

VS2012 update1 下载参考

http://www.microsoft.com/visualstudio/eng/downloads#d-visual-studio-2012-update

该问题适用于 用 HCK 2.1  安装  HCK Client 的时候,点击 Setup.exe 报告“不是有效的WIN32 应用”。