代码之家  ›  专栏  ›  技术社区  ›  RichieHindle

你能解释一下.NET运行时的这种奇怪崩溃吗?

  •  5
  • RichieHindle  · 技术社区  · 15 年前

    当我的C应用程序抛出一个未处理的异常时,它会向我发送一个堆栈跟踪,而我现在正在查看一个我不明白的异常。

    看起来这不可能是我的错,但通常当我认为我后来被证明是错的时候。8-)下面是堆栈跟踪:

    mscorlib caused an exception (ArgumentOutOfRangeException): startIndex cannot be larger than length of string.
    Parameter name: startIndex
       System.String::InternalSubStringWithChecks(Int32 startIndex, Int32 length, Boolean fAlwaysCopy) + 6c
       System.String::Substring(Int32 startIndex) + 0
       System.IO.Directory::InternalGetFileDirectoryNames(String path, String userPathOriginal, String searchPattern, Boolean includeFiles, Boolean includeDirs, SearchOption searchOption) + 149
       System.IO.Directory::GetFiles(String path, String searchPattern, SearchOption searchOption) + 1c
       System.IO.Directory::GetFiles(String path) + 0
       EntrianSourceSearch.Index::zz18ez() + 19b
       EntrianSourceSearch.Index::zz18dz() + a
    

    所以我的代码(末尾的模糊函数名)调用 System.IO.Directory.GetFiles(path) 它会因字符串索引问题而崩溃。

    可悲的是我不知道 path 但不管怎样,肯定不可能 System.IO.Directory::GetFiles 像那样崩溃?尽我所能我想不出任何理由 GetFiles 再现了坠机事件。

    我是否真的在.NET运行时中看到了一个bug,或者是否有什么东西可以合法地导致此异常?(如果我打电话时目录被更改,我可以理解出问题 获取文件 ,但在那种情况下我不会期望字符串索引异常。

    编辑 :感谢大家的想法!到目前为止,最有可能的理论是有一个路径名,其中包含不可靠的非BMP-Unicode字符,但我仍然无法使其中断。查看中的代码 获取文件 有了反射镜,我想它唯一能打破的方法就是 GetDirectoryName() 返回一条 比较长的 而不是它的输入,即使它的输入已经完全正常化了。奇怪的。我试过用非BMP字符创建路径名(我从未有过名为{music SYMBOL]的目录 8-)之前的谱号,但我还是不能把它弄断。

    我所做的是在失败的代码周围添加额外的日志记录(并确保我的日志记录使用非BMP字符!)如果再次发生,我会得到更多的信息。

    9 回复  |  直到 15 年前
        1
  •  2
  •   Lucas    15 年前

    你可以试着查一下 System.IO.Path.GetFiles() 具有 .NET Reflector . 从一个快速的看,它显然只是 String.Substring() 将某物从路径的末端拆分并将其添加回方法的末端附近。它检查 Path.DirectorySeparatorChar (反斜杠, '\' )以及 Path.AltDirectorySeparatorChar (斜线, '/' )以确定子字符串的索引和长度。

    我的猜测是无效的或unicode文件或文件夹名称混淆了方法。

        2
  •  1
  •   Matt Hamsmith Rahul Singh    15 年前

    只是一个猜测。。。作为参数传递的文件名是否超过256个字符?.Net framework标准System.IO函数无法处理超过该长度的文件名。

        3
  •  1
  •   lb.    15 年前

    真 的。。我想我从来没有这样过。

    你是说只有这一个顾客才会这样?

    1. 可能想开始记录路径参数,并设置程序将日志发送给您进行分析,我觉得问题出在参数的格式上。
    2. 如果这个模糊代码是从您自己的模糊处理程序创建的,为什么不尝试在您的计算机上用收集的一些参数测试它并查看结果?
    3. 在路径命名空间中没有任何东西,比如PATION .Engor(或).PATION.ISVALUTE()来给参数一个检查。可能有有趣的“/”或“\”和其他字符,所以当内部API解析每个组件时,由于有趣的字符,在确定路径字符串的每个部分时会出现某种损坏?只是一个观察,因为子字符串失败了。

    希望有帮助,祝你好运!请让我们知道你找到的解决方案是什么,因为肯定会是一个有趣的。

        4
  •  1
  •   Joe Caffeine    15 年前

    也许你可以提供一些关于客户有问题的细节。例如: 一。操作系统名称和版本 2。操作系统支持语言 三。您要瞄准的.Net版本,与客户正在运行的.Net版本相比。

    目录路径中可能有unicode字符,导致字符串长度被一个或多个关闭。

    另一个注释:异常文本表明您的程序是用托管C++编写的。您不是在任何非托管字符串操作中混合,是吗?

    如果可以的话,我建议修改诊断以捕获导致错误的实际路径变量。 一个可能的合理解释: http://support.microsoft.com/kb/943804/

        5
  •  1
  •   AMissico    15 年前

    第一个也是唯一的问题应该是,“你的运行ChkDsk了吗?”

        6
  •  0
  •   Henri    15 年前

    也许这和混淆器有关。而那个混蛋把事情搞砸了。试着在没有混淆器的情况下运行代码。发布你的结果。

    编辑: 你能再现坠机事件吗?

        7
  •  0
  •   GavinGavin    15 年前

    不确定这是相关的,但我正在使用VisualC++中的GETFILE,当它列出C的内容时,它崩溃了,原来我有一个文件夹,它以前安装了一个混乱的权限。我将文件夹回收给当前用户,并修复了崩溃。

        8
  •  0
  •   Anton PAnton P    15 年前

    是否有可能快速编写控制台应用程序并在调试模式下运行它。基本上使用GetFiles方法循环遍历整个文件目录。也许会有什么东西撞到你,你应该能很快找到违规文件?

        9
  •  0
  •   AMissico    15 年前

    从souce和您的评论来看,我怀疑UNC路径导致了问题,可能是安全权限或共享权限问题。例如,如果用户关闭了8.3文件名的创建,则肯定会出现UNC路径问题,因为这会导致网络提供程序无法在Windows 2000和Windows XP中检索正确的文件名。(我忘记修复了此错误的服务包。)

    下面是重要的源代码。

        String tempStr = Path.InternalCombine(fullPath, searchPattern);
    
        // If path ends in a trailing slash (\), append a * or we'll
        // get a "Cannot find the file specified" exception
        char lastChar = tempStr[tempStr.Length-1];
        if (lastChar == Path.DirectorySeparatorChar || lastChar == Path.AltDirectorySeparatorChar || lastChar == Path.VolumeSeparatorChar) 
            tempStr = tempStr + '*';
    
        fullPath = Path.GetDirectoryName(tempStr); 
        BCLDebug.Assert((fullPath != null),"fullpath can't be null!");
    
        String searchCriteria;
        bool trailingSlash = false;
        bool trailingSlashUserPath = false;
    
        lastChar = fullPath[fullPath.Length-1];
        trailingSlash = (lastChar == Path.DirectorySeparatorChar) || (lastChar == Path.AltDirectorySeparatorChar); 
    
        if (trailingSlash) {
            // Can happen if the path is C:\temp, in which case GetDirectoryName would return C:\ 
            searchCriteria = tempStr.Substring(fullPath.Length);
        }
        else
            searchCriteria = tempStr.Substring(fullPath.Length + 1);