В компании, в которой я работаю, на некоторых из нас повлияла ошибка / ошибка в Visual Studio. Отладчику не удается отобразить значение / содержимое std :: string. Он говорит: «Ошибка чтения символов строки.»
Некоторые фотографии проблемы: Простые строковые переменные Значения в отладчике
Следующая строка будет всегда воспроизводить проблему, но, как правило, каждая строка в коде (по крайней мере, ~ 1'000'000 строк) будет иметь проблему.
std::string testVar = "Something";
Редактировать: Попытка сделать минимальный воспроизводимый пример в ближайшее время, но сейчас я не могу сделать один. Проблема возникает только в одном решении, состоящем из 93 проектов. До сих пор пробовал: Новое решение с той же версией компилятора (v120), любой версией компилятора, одинаковыми определениями препроцессора, VS2013 и VS2017 (обе проблемы возникают в Professional и Enterprise). Теперь устанавливаю VS2019, чтобы протестировать его.
Я строю строку из const char *, так что это, вероятно, не имеет ничего общего с распределением памяти, et c ... И, самое главное, код работает. Итак, сама std :: string работает так, как должна, но отладчик не может показать ее значения. Размер правильный, насколько я вижу, но емкость всегда 0x cccccccccccccccc. Для символов в строке написано: «Невозможно прочитать память». Подробное представление строки в отладчике
Эта проблема возникает только с std :: string, а не с std :: wstring или char * или чем-либо еще. Кроме того, когда я открываю новое решение, std :: string будет отображаться правильно. Он не отображается только в решении с более чем 91 проектом. Воспроизводится в VS2017 и VS2013, но мы используем компилятор v120. Пробовал константные переменные и имел переменную в куче или в стеке, это не имеет значения.
Кроме того, это происходит только в отладочной сборке, в режиме выпуска отладчик работает просто отлично.
Эта ошибка присутствует с этой недели, мы не могли наблюдать ничего подобного раньше или даже больше, чем за неделю go. У 3 из нас есть эта проблема, но у некоторых других нет. Мы все работаем в основном на одних и тех же машинах с одинаковыми настройками и обновлениями. Единственное отличие состоит в том, что рабочая VS - это Professional, и мы используем версию Enterprise.
Я знаю, что это не является серьезной проблемой, так как код работает, но это иногда делает отладку намного более сложной.
Редактировать: Может быть важно, что при отладке с помощью пошаговых инструкций отладчик не входит в конструктор или любую из функций std :: string (в xstring), он просто переходит это как бы простое присваивание переменной int, а не вызов функции. Но установка точки останова в исходном коде std :: string на самом деле будет работать, и отладчик на этом остановится.
EDIT2 - найдена причина ошибки, но пока нет реального решения
После анализа значений указателей в std :: string я обнаружил, почему отладчику не удается извлечь строку. Отладчик ищет его со смещением +8 байт. Чтобы объяснить это: допустим, я создал std :: string и получил его указатель.
std::string testStr = "test";
std::string* strPtr = &testStr;
Затем strPtr = 0x0000000001bdf4a8. Теперь, когда я смотрю в окно «Локальные» отладчика, смотрю необработанное представление строки и нахожу указатель в объединении _Bx, то: _Buf = 0x0000000001bdf4b0 Это strPtr + 8. Вот почему он не может декодировать содержимое строки. потому что он пытается интерпретировать это не по адресу. Если бы я сделал это:
std::string* fixedStr = reinterpret_cast<std::string*>(reinterpret_cast<char*>(&testStr)-8);
Итак, когда я вручную уменьшу указатель на 8 байт и преобразую его в строку, отладчик будет правильно отображать его содержимое. (Конечно, эта строка повреждена и не будет работать, только отображение отладчика исправлено)
Когда я открываю новое решение и смотрю на адреса строки таким же образом, отладчик показывает тот же адрес для _Buf как указатель строки, который является нормальным поведением. Разница между ними заключается в том, что когда он не может декодировать строку, std :: _ Container_base имеет тип std :: _ Container_base12 и имеет содержимое, а когда он работает, он имеет std :: _ Container_base0 и имеет нулевое содержимое. Это дополнительное содержимое, вероятно, вызывает дополнительные 8 байтов.
Связанные вещи, которые я нашел, но не предлагал решения (пробовал методы здесь, но проблема не устранена): Visual C ++ 2010 отказывается показывать std :: string значение при отладке. шоу
В отладчике Visual Studio неправильно отображается std :: string при отладке
https://developercommunity.visualstudio.com/content/problem/782573/visual-studio-debugger-doesnt-display-stdstring-pr.html
Также попытался возиться с natvis в соответствии с этим: Как визуализировать простую строку std :: string с natvis?