From:http://www.educity.cn/wenda/351190.html

GetAdaptersInfo函数在64位系统下返回ERROR_NOACCESS的问题

  实际应用中一个程序在长时间运行后内存占用较高时发生崩溃,从dump信息中,发现GetAdaptersInfo函数返回了一个奇怪的错误码998(ERROR_NOACCESS),百度搜索不到相关的信息。MSDN上GetAdaptersInfo函数的错误码正常情况下只有5种。并且一共发生的两次崩溃都出现在一台Win7 64位机器上,其他测试机器均正常。

  有问题的代码如下:

  void GetMacAddr(char *buf) { BOOL bNewState = TRUE; //PIP_ADAPTER_INFO结构体指针存储本机网卡信息 PIP_ADAPTER_INFO pIpAdapterInfo = new(std::nothrow) IP_ADAPTER_INFO; if (pIpAdapterInfo == NULL) { return; } //得到结构体大小,用于GetAdaptersInfo参数 unsigned long stSize = sizeof(IP_ADAPTER_INFO); //调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量;其中stSize参数既是一个输入量也是一个输出量 ULONG ulRel = GetAdaptersInfo (pIpAdapterInfo, &stSize); if (ERROR_BUFFER_OVERFLOW == ulRel) { bNewState = FALSE; delete pIpAdapterInfo; //重新申请内存空间用来存储所有网卡信息 pIpAdapterInfo = (PIP_ADAPTER_INFO)new(std::nothrow) BYTE[stSize]; if (pIpAdapterInfo == NULL) { return; } //再次调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量 ulRel = GetAdaptersInfo (pIpAdapterInfo, &stSize); } string strIpMac; if (ERROR_SUCCESS==ulRel) { //输出网卡信息 //可能有多网卡,因此通过循环去判断 PIP_ADAPTER_INFO pIpAdapterInfoTmp = pIpAdapterInfo; while (pIpAdapterInfoTmp != NULL) { char szMac[10] = {0}; for (UINT i =0; i < pIpAdapterInfoTmp->AddressLength; i++) { if (i==pIpAdapterInfoTmp->AddressLength-1) { _snprintf_s(szMac, 10, "%02x;", pIpAdapterInfoTmp->Address[i]); strIpMac += szMac; } else { _snprintf_s(szMac, 10, "%02x-", pIpAdapterInfoTmp->Address[i]); strIpMac += szMac; } } pIpAdapterInfoTmp = pIpAdapterInfoTmp->Next; } } //释放内存空间 if (pIpAdapterInfo != NULL) { if (bNewState == FALSE) { delete[] pIpAdapterInfo; } else { delete pIpAdapterInfo; } } if (strIpMac[strIpMac.length()-1] == ';') { strIpMac[strIpMac.length()-1] = '\0'; } sprintf(buf,"%s",strIpMac.c_str()); return; }

  Return code

  Description

  ERROR_BUFFER_OVERFLOW

  The buffer to receive the adapter information is too small. This value is returned if the buffer size indicated by the pOutBufLen parameter is too small to hold the adapter information or the pAdapterInfo parameter was a NULL pointer. When this error code is returned, the pOutBufLen parameter points to the required buffer size.

  ERROR_INVALID_DATA

  Invalid adapter information was retrieved.

  ERROR_INVALID_PARAMETER

  One of the parameters is invalid. This error is returned if the pOutBufLen parameter is a NULL pointer, or the calling process does not have read/write access to the memory pointed to by pOutBufLen or the calling process does not have write access to the memory pointed to by the pAdapterInfo parameter.

  ERROR_NO_DATA

  No adapter information exists for the local computer.

  ERROR_NOT_SUPPORTED

  The GetAdaptersInfo function is not supported by the operating system running on the local computer.

  Other

  If the function fails, use FormatMessage to obtain the message string for the returned error.

  所以我们将问题锁定为Win7 64位机器,内存占用高,GetAdaptersInfo函数返回998错误。

  为此我们编写了一个测试程序,创建两个线程,一个线程不断申请内存,一次申请500KB,另外一个线程循环调用GetAdaptersInfo函数,直到返回998错误。

  测试结果验证了我们的猜测。

  自此原因查明,程序代码在返回998的时候未做判断,对申请的内存进行了delete操作引起了崩溃,而998代表ERROR_NOACCESS即不能访问,所以应该进行判断。

  在这个问题解决后不久,微软的Bug报告及建议网站上找到了一篇文章,$amp;<lt;$strong>GetAdaptersAddresses API incorrectly returns no adapters for a process with high memory consumption>, rrectly-returns-no-adapters-for-a-process-with-high-memory-consumption.一位国外程序员同样重现了此问题,但微软方面至今未给出解决方案,只确认了这属于Windows操作系统的一个Bug。在他的描述中更详细的指明了发生条件:

  1.32-bit application

  2.64-bit operating system or /3GB feature enabled on 32-bit operating system

  3.hosting process is linked with /LARGEADDRESSAWARE flag or has otherwise set it in binary header

  4.over 2GB of RAM (in terms of Private Bytes/Virtual Size performance counters) consumed by the hosting process

  即32位程序,运行在64位操作系统,超过2GB的进程内存占用,同样佐证了我们的猜测。

【转载】GetAdaptersInfo函数在64位系统上返回ERROR_NOACCESS的有关问题的更多相关文章

  1. [转]C#程序无法在64位系统上运行之.NET编译的目标平台

    今天将编译的C#的exe拷贝到测试机上(Win7_64bit),一运行就挂了,提示“stop working”,一开始怀疑测试机上没有安装.net framework框架,追究半天原来是编译的目标平台 ...

  2. 【转】将 Linux 应用程序移植到 64 位系统上

    原文网址:http://www.ibm.com/developerworks/cn/linux/l-port64.html 随着 64 位体系结构的普及,针对 64 位系统准备好您的 Linux® 软 ...

  3. 在64位系统上不能安装Matlab notebook的解决方案

    在64位系统上不能安装Matlab notebook的解决方案 过程分解 第一步:安装好matlab(附:Matalab R2015a界面) 第二步:在matlab中执行命令 >>note ...

  4. 在window server 2008 64位系统上 发布网站的过程中遇到的问题(转)

    发布网站的过程如下: 1.安装数据库系统2.建立数据库,执行sql3.安装iis4.在本地机子上发布网站5.把发布好的东西拷贝到IIS上 1.安装数据库系统: 出现错误:必须使用角色管理工具 安装或配 ...

  5. 在window server 2008 64位系统上 发布网站的过程中遇到的问题

    发布网站的过程如下: 1.安装数据库系统2.建立数据库,执行sql3.安装iis4.在本地机子上发布网站5.把发布好的东西拷贝到IIS上 1.安装数据库系统: 出现错误:必须使用角色管理工具 安装或配 ...

  6. 如何在64位系统上安装SQL Server 2000

    如何在64位系统上安装SQL Server 2000? 现在用SQL Server 2000数据库的人少了吧?大都是SQL Server 2005/2008了.不过还是有需求的,今天一朋友就让我在他的 ...

  7. Win7 64位系统上配置使用32位的Eclipse(转)

    Win7 64位系统上配置使用32位的Eclipse 博客分类: Eclipse eclipse  最近工作电脑换成了64位的win7系统,之前个人电脑上安装的jdk和Eclipse都是32位的.而新 ...

  8. 32位程序在64位系统上获取系统安装时间(要使用KEY_WOW64_64KEY标记)

    众所周知,取系统的安装时间可取注册表HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion的子项InstallDate,此值是个 ...

  9. 使用visual c++ 2005远程调试64位系统上32位与64位程序

    一直都挺喜欢使用visual c++远程调试代码,它能展现给我们当时代码执行最真实的情景,今天有时间记录一下,以免以后忘了. 远程调试需要在被调试端安装服务器,对于visual c++ 2005来说调 ...

随机推荐

  1. 记录一次代码错误,elastic search的INDEX需要使用小写字母

    Caused by: org.elasticsearch.hadoop.EsHadoopIllegalArgumentException: Cannot determine write shards ...

  2. mfc学习---文档视图架构

    MFC的AppWizard可以生成三种类型的应用程序:基于对话框的应用.单文档应用(SDI)和多文档应用(MDI).   一般情况下,采用文档/视结构的应用程序至少应由以下对象组成:       1. ...

  3. 将从数据库中获取的数据写入到Excel表中

    pom.xml文件写入代码,maven自动加载poi-3.1-beta2.jar <!-- https://mvnrepository.com/artifact/poi/poi --> & ...

  4. jQuery带小图标的Tab切换焦点图

    在线演示 本地下载

  5. 【传感器】BMA253 数字,三轴加速度传感器

    参考文档:BMA253E DataSheet 参考文档链接 密码:9new BMA253 数字,三轴加速度传感器 关键特性: 关键特性   封装方式 LGA封装(12pins),长*宽(2mm*2mm ...

  6. java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[]]

    1.问题描述: 对于创建的springboot项目,通过启动类启动,访问没问题,但打成war部署到tomcat上启动报错,如下: 严重: ContainerBase.addChild: start: ...

  7. 关于MySQL的TinyInt数据类型在Delphi中作为Boolean类型的一个要注意的问题

    关于MySQL的TinyInt数据类型在Delphi中作为Boolean类型的一个要注意的问题: 在定义TinyInt类型字段时,若要作为Delphi中作为Boolean类型,则该字段的长度必须为1!

  8. quartz(2) -- 入门案例

    第一步:添加jar,maven配置 <!-- quartz --> <dependency> <groupId>org.quartz-scheduler</g ...

  9. Dos命令的巧用 - 转载

    Dos命令的巧用 豪华绚丽的Windows让人们把DOS抛到遥远的记忆角落,然而,真正有价值的东西不会轻易退出历史的舞台.很多人都已经习惯于 Windows的图形化用户界面,熟不知古老的DOS命令却可 ...

  10. ftp禁止切换回上级目录

    打开并编辑/etc/vsd/vsd.conf # vi /etc/vsd/vsftpd.conf 取消如下行注释 chroot_list_enable=YES 保存并重启vsftpd # /etc/i ...