Неверный номер строки в трассировке стека

Я работаю с sdk 23.1.0 и gradle 1.3.1. Я создал новый проект, ничего не отредактировал и получил ошибку helpl. Я вошел в свой проект gradle file и изменил инструмент на 22.0.1 вместо 23.1.0, и он работал:

   compileSdkVersion 23
   buildToolsVersion "22.0.1" //"23.1.0"
30
задан Claudio Redi 22 March 2010 в 16:31
поделиться

3 ответа

Да, это ограничение в логике обработки исключений. Если метод содержит более одного оператора throw, который генерирует исключение, вы получите номер строки, в которой он был последним. Этот пример кода воспроизводит следующее поведение:

using System;

class Program {
    static void Main(string[] args) {
        try {
            Test();
        }
        catch (Exception ex) {
            Console.WriteLine(ex.ToString());
        }
        Console.ReadLine();
    }
    static void Test() {
        try {
            throw new Exception();  // Line 15
        }
        catch {
            throw;                  // Line 18
        }
    }
}

Вывод:

System.Exception: Exception of type 'System.Exception' was thrown.
   at Program.Test() in ConsoleApplication1\Program.cs:line 18
   at Program.Main(String[] args) in ConsoleApplication1\Program.cs:line 6

Обход прост: просто используйте вспомогательный метод для запуска кода, который может вызвать исключение.

Примерно так:

static void Test() {
    try {
        Test2();                // Line 15
    }
    catch {
        throw;                  // Line 18
    }
}
static void Test2() {
    throw new Exception();      // Line 22
}

Основная причина такого неудобного поведения заключается в том, что обработка исключений .NET построена на основе поддержки исключений операционной системой. Называется SEH, структурированная обработка исключений в Windows. Это основано на кадрах стека, в каждом кадре стека может быть только одно активное исключение. У метода .NET один фрейм стека, независимо от количества блоков области видимости внутри метода. Используя вспомогательный метод, вы автоматически получаете еще один кадр стека, который может отслеживать собственное исключение.Джиттер также автоматически подавляет оптимизацию встраивания, когда метод содержит оператор throw , поэтому нет необходимости явно использовать атрибут [MethodImpl].

36
ответ дан 27 November 2019 в 23:37
поделиться

Соответствует ли дата / время вашего файла .pdb вашему файлу .exe / .dll? В противном случае возможно, что компиляция не находится в «режиме отладки», который генерирует новый файл .pdb при каждой сборке. В файле pdb указаны точные номера строк при возникновении исключений.

Проверьте настройки компиляции, чтобы убедиться, что генерируются данные отладки, или, если вы находитесь в тестовой / производственной среде, проверьте файл .pdb, чтобы убедиться, что метки времени совпадают.

5
ответ дан 27 November 2019 в 23:37
поделиться

Трассировка стека в C# генерируется во время броска, а не во время создания исключения.

Это отличается от Java, где трассировка стека заполняется во время создания исключения.

Очевидно, так и задумано.

3
ответ дан 27 November 2019 в 23:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: