2009-08-24 11 views
5

Moja aplikacja C# wysyła mi ślad stosu, gdy zgłasza nieobsługiwany wyjątek, a teraz patrzę na taki, którego nie rozumiem.Czy możesz wyjaśnić tę dziwaczną awarię w środowisku wykonawczym .NET?

Wygląda na to, że to nie może być moja wina, ale zazwyczaj kiedy myślę, że później okazałem się nie tak. 8-) Oto ślad stosu:

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 

Więc moja Kodeksu (ukrywane nazwy funkcji na końcu) wzywa System.IO.Directory.GetFiles(path) który zderza się z problemem indeksowania ciąg.

Niestety nie znam wartości path, która została przekazana, ale niezależnie od tego, na pewno nie powinno być możliwe, aby System.IO.Directory::GetFiles zawiesił się w ten sposób? Spróbuj, jak mogę, nie mogę wymyślić żadnego argumentu do GetFiles, który odtwarza awarię.

Czy naprawdę patrzę na błąd w środowisku wykonawczym .NET, czy jest coś, co może legalnie powodować ten wyjątek? (Mogę zrozumieć rzeczy dzieje się źle, jeśli katalog był zmieniony w czasie zadzwoniłem GetFiles, ale nie spodziewałbym wyjątek indeksowania ciąg w tym przypadku).

Edit: Dzięki wszystkim za ich myśli! Najbardziej prawdopodobną do tej pory teorią jest to, że istnieje ścieżka z podejrzanymi znakami Unicode nie-BMP, ale nadal nie mogę jej złamać. Patrząc na kod w GetFiles z Reflectorem, myślę, że jedynym sposobem jego złamania jest, aby GetDirectoryName() zwrócił ścieżkę o numerze dłuższą o niż swoje wejście, nawet jeśli wejście jest już w pełni znormalizowane. Dziwaczny. Próbowałem tworzyć ścieżki zawierające znaki spoza BMP (nigdy przedtem nie miałem katalogu o nazwie {MUSICAL SYMBOL G CLEF}), ale nadal nie mogę go złamać.

To, co zrobiłem, to dodać dodatkowe rejestrowanie wokół błędnego kodu (i upewnić się, że moje logowanie działa na znakach innych niż BMP!). Jeśli to się powtórzy, będę miał o wiele więcej informacji.

+0

Być może próbuje on spojrzeć na katalog z uszkodzonymi nazwami plików? –

+1

Jaka jest wartość parametru w System.IO.Directory:: GetFiles(String path) + 0? – Yakeen

+0

Czy twoja aplikacja zawiera dowolny natywny kod? –

Odpowiedz

0

Być może ma to coś wspólnego z obfuscatorem. A obmacawca podkręca rzeczy. Spróbuj uruchomić kod bez obfuscatora. I opublikuj swoje wyniki.

edycja:Czy jesteś w stanie odtworzyć awarię?

+0

... nie zna danych wejściowych, które spowodowały wyjątek. – JoshJordan

+0

@Henri: Ten sam zamaskowany kod działa dobrze dla wszystkich innych - jest tylko jeden klient z awarią. Nie sądzę, żeby obfuscator był trafny. Wszystko, co robi, to przekazywanie ciągów do GetFiles - w jaki sposób zaciemnienie może je zmącić? 8-) I nie, nie jestem w stanie odtworzyć katastrofy. – RichieHindle

+0

Obfuskacja może zrobić dziwne rzeczy do kodu .NET. Jeśli obfuscator robi rzeczy takie jak wstrzyknięcie fałszywego kodu i tym podobne, twoja logika programowa nie jest już dokładnie taka sama jak przed zaciemnieniem. Mam wrażenie, że robi coś, co zmusza do manipulowania danymi wejściowymi. Możesz zobaczyć, czy możesz wyłączyć tę funkcję z zaciemniania i sprawdzić, czy to rozwiązuje problem. – Navaar

1

Zgadnij ... czy któreś z nazw plików przekazanych jako argumenty dłuższe niż 256 znaków? Standardowe funkcje System.IO w ramach frameworka .Net nie są w stanie obsłużyć nazwy pliku dłuższej.

+0

Niestety - wygenerowałoby to wyjątek PathTooLongException, a nie błąd. –

+0

@Matt: To coś, o czym nie myślałem, ale myślę, że masz rację, dałoby to oczywisty wyjątek, a nie dziwny. Spędziłem dużo czasu, próbując złamać 'GetFiles', podając mu zepsute argumenty, i niezmiennie wyrzuca mi rozsądny wyjątek. – RichieHindle

+0

Sprawdziłem oficjalną dokumentację (jak na pewno masz), a ArgumentOutOfRangeException nie jest nawet wymieniony jako jeden z wyjątków, które ta funkcja może wyrzucić. Jedyne, co nawet zdaje się być bliskie temu, co przychodzi mi do głowy, to znak wieloznaczny lub względna ścieżka wymagająca rozszerzenia - wszelkie dane, które należy rozwinąć, aby stworzyć absolutną ścieżkę, jak wskazuje Lucas. –

2

Możesz spróbować zajrzeć do kodu dla System.IO.Path.GetFiles() z .NET Reflector. Z szybkiego spojrzenia najwyraźniej tylko wywołuje String.Substring(), aby podzielić coś od końca ścieżki i dodaje ją z powrotem pod koniec metody. Sprawdza Path.DirectorySeparatorChar (ukośnik odwrotny, '\') i Path.AltDirectorySeparatorChar (ukośnik, '/'), aby określić indeks i długość podciągu.

Domyślam się, że nieprawidłowe nazwy plików lub folderów niepoprawne lub unicode powodują zamieszanie w tej metodzie.

+0

@Lucas: Wygląda na to, że jedynym sposobem, w jaki można go złamać, jest funkcja 'GetDirectoryName()', która zwraca ścieżkę dłuższą niż jej dane wejściowe, nawet jeśli jej dane wejściowe są już w pełni znormalizowane. Dziwaczny. I nie mogę wymyślić ścieżki, która to umożliwia. – RichieHindle

1

Wow .. Nie sądzę, że kiedykolwiek mi się to przydarzyło.

Mówisz, że to tylko ten jeden klient, że tak się dzieje?

  1. Może chcesz rozpocząć rejestrowanie parametrów ścieżki i skonfigurować program do wysyłania dzienników do analizy, uważam, że problem jest w formacie argumentu.
  2. Jeśli ten zaciemniony kod został utworzony z własnego obfuscatora, dlaczego nie wypróbujesz go na "nieoczyszczonym" urządzeniu z niektórymi zebranymi parametrami i zobaczysz wynik?
  3. Czy w obszarze nazw Path nie ma nic, na przykład Path.Exist() lub Path.IsValid(), aby dać parametrowi czek. Może jest tam zabawne "/" lub "\" i inne znaki, więc kiedy wewnętrzne interfejsy API analizują każdy komponent, czy jest jakiś rodzaj korupcji w określaniu każdej części łańcucha ścieżki z powodu zabawnych postaci? Tylko obserwacja, ponieważ Substring zawodzi.

Nadzieję, że pomaga i powodzenia! Daj nam znać, jakie jest rozwiązanie, które z pewnością będzie interesujące.

+0

@Leo: 1. Więcej logowania, tak, już to zrobiłem dla następnej wersji. 8-) 2. Zrobi. 3. 'GetFiles' już chroni się przed tym wszystkim - zobacz mój komentarz do odpowiedzi Matta http://stackoverflow.com/questions/1324806/can-you-explain-this-bizarre-crash-in-the-net-runtime/1324846 # 1324846 – RichieHindle

1

Być może możesz podać kilka szczegółów na temat klienta, który go ma. Rzeczy typu: 1. Nazwa i wersja systemu operacyjnego 2. Język systemu operacyjnego 3. Wersja sieciowa, na którą kierujesz, w porównaniu z wersją .Net, z której korzysta klient.

W ścieżce katalogów mogą znajdować się znaki Unicode powodujące wyłączenie długości ciągu o jeden lub więcej.

Kolejna uwaga: tekst wyjątku sugeruje, że Twój program został napisany w zarządzanym C++. Nie mieszasz się w żadnej niezarządzanej manipulacji ciągami, prawda?

Mogę zasugerować, że jeśli możesz, zmodyfikuj swoją diagnostykę, aby uchwycić rzeczywistą zmienną ścieżki, która powoduje błąd. Możliwe wiarygodne wyjaśnienie: http://support.microsoft.com/kb/943804/

+0

@Joe: XP-32 SP3, angielski, 2.0, 2.0.50727.1433 (który komentarze Earwicker to 3.5 bez SP1). To wszystko C# (składnia podobna do C++ w śledzeniu stosu jest taka, że ​​są one sformatowane przez mój własny kod, a ja jestem raczej facetem C++ niż facetem C# 8-) – RichieHindle

+0

Technicznie, 2.0.50727.1433 jest 2.0 SP1 . Dodatek 2.0 SP1 można uzyskać, aktualizując instalację 2.0 lub instalując wersję 3.5 (bez dodatku SP1), która instaluje dodatki 2.0 SP1 i 3.0 SP1 jako wymagania wstępne. – Lucas

1

Pierwsze i jedyne pytanie powinno brzmieć: "Czy chcesz uruchomić ChkDsk?"

0

Nie jestem pewien, czy to jest powiązane, ale korzystam z GetFiles w Visual C++, powodowało awarię podczas wyświetlania zawartości C :, okazało się, że mam folder z pomieszanymi uprawnieniami z poprzedniej instalacji. Odzyskałem folder do mojego obecnego użytkownika i naprawiłem awarię.

+0

@Gavin: Czy wiesz, czym był wyjątek? – RichieHindle

0

Podejrzewam, że ścieżka UNC powoduje problemy, z możliwymi uprawnieniami zabezpieczeń lub problemem uprawnień do udostępniania. Na przykład, jeśli użytkownik wyłączył tworzenie nazw plików 8.3, na pewno wystąpią problemy ze ścieżką UNC, ponieważ powoduje to, że dostawca sieci nie może poprawnie odczytać nazw plików w systemach Windows 2000 i Windows XP. (Zapomniałem, które pakiety serwisowe ten błąd został naprawiony.)

Poniżej znajduje się kod źródłowy o znaczeniu.

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); 
0

Jest to możliwość szybkiego zakodowania aplikacji konsolowej i uruchomienia jej w trybie debugowania. Zasadniczo przeprowadź pętlę przez cały katalog plików przy użyciu metody GetFiles. Może coś uderzy i powinieneś być w stanie szybko zlokalizować szkodliwy plik?

+0

To zdarzyło się tylko na komputerze klienta, więc klient musiałby to zrobić. Według mojej wiedzy to się już nie powtórzyło, więc może AMissico miał rację ze swoją sugestią ChkDsk. – RichieHindle

Powiązane problemy