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. nodejs两个例子

    1.nodejs多线程 var cluster=require("cluster");//ͨ¹ýcluster¿ÉÒÔ·Ö³öһЩ×ÓÏß³Ì var http=requir ...

  2. JS 原生JS 判断滚动条滑动到底部

    window.addEventListener("scroll", function(event) { var scrollTop = document.documentEleme ...

  3. Linux性能测试分析命令_sar+iostat+vmstat+top

    sar主要用于收集并统计系统资源的信息,包括CPU.IO.内存.网卡流量等. vmstat命令主要是对操作系统的虚拟内存.进程.IO读写.CPU活动等整体情况进行统计.但是它不能对某个进程进行深入分析 ...

  4. Samba 3.6.9 安装、管理

    Samba简介 Samba服务类似于windows上的共享功能,可以实现linux上共享文件,windows上访问,当然在linux上可以访问到.是一种在局域网上共享文件和打印机的一种通信协议,它为局 ...

  5. 20145201 《Java程序设计》第五周学习总结

    20145201 <Java程序设计>第五周学习总结 教材学习内容总结 本周学习了课本第八.九章内容,即异常处理.Collection与Map. 第八章 异常处理 8.1 语法与集成架构 ...

  6. Asp.net Core, 基于 claims 实现权限验证 - 引导篇

    什么是Claims? 这个直接阅读其他大神些的文章吧,解释得更好. 相关文章阅读: http://www.cnblogs.com/JustRun1983/p/4708176.html http://w ...

  7. 第二篇:Spark SQL Catalyst源码分析之SqlParser

    /** Spark SQL源码分析系列文章*/ Spark SQL的核心执行流程我们已经分析完毕,可以参见Spark SQL核心执行流程,下面我们来分析执行流程中各个核心组件的工作职责. 本文先从入口 ...

  8. ScrollView嵌套使用ListView冲突的解决与分析

    因为ScrollView与ListView都是具有滚动条的控件,所以嵌套在一起使用的时候可能会出现事件的冲突,比如我就遇见了ListView中只显示一条数据的问题.解决的办法,就是自定义了一个List ...

  9. CocoaPods学习系列4——进阶用法

    这篇文章,记录一下CocoaPods的进阶用法. 进阶用法主要体现在.podspec文件和Podfile的配置上. .podspec文件的进阶配置 以官方的一个.podspec文件示例细说: Pod: ...

  10. tyvj 1059 过河 dp

    P1059 过河 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 NOIP2005 提高组 第二道 描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳 ...