Я отправил это в Apple как ошибку, но просто для подтверждения вот тестовый код:
#include <string>
std::string home_directory;
std::string BuildPath(const std::string directory, const std::string path)
{
if(home_directory.compare(directory) == 0)
printf("In home directory\n");
return directory + "/" + path;
}
int main(int, char* [])
{
home_directory = "home";
printf("Home: '%s'\n", home_directory.c_str());
printf("BuildPath: '%s'\n", BuildPath("base", "path").c_str());
}
При сборке с последними версиями XCode 5.1, iOS SDK 7.1 и LLVM 5.1 с использованием libstdc++ для стандартной библиотеки C++ происходит сбой где-то в реализации std::string в строке возврата из функции BuildPath при запуске на устройстве iOS 5.1.
Выход
Home: 'home'
CrashTest(1242) malloc: *** error for object 0x2fe2ac80: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Сканирование стека:
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x00000000, 0x00000000
Crashed Thread: 0
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x34fb8848 __kill + 8
1 libsystem_c.dylib 0x36eae2ae abort + 110
2 libsystem_c.dylib 0x36e6937a free + 374
3 libstdc++.6.dylib 0x3481a93a operator delete(void*) + 6
4 libstdc++.6.dylib 0x34806138 std::string::_Rep::_M_dispose(std::allocator<char> const&) + 68
5 libstdc++.6.dylib 0x34806c04 std::string::reserve(unsigned long) + 156
6 libstdc++.6.dylib 0x34806daa std::string::append(char const*, unsigned long) + 70
7 CrashTest 0x00094a30 BuildPath(std::string, std::string) (basic_string.h:2121)
8 CrashTest 0x00094bda main (main.cpp:25)
9 CrashTest 0x0009499c start + 32
С уровнями оптимизации -O1 или ниже или с использованием libc++ в качестве стандартной библиотеки все работает так, как ожидалось. Он также работает должным образом на iOS 6 или 7. При сборке с предыдущим выпуском XCode (5.0.2, iOS SDK 7.0 и LLVM 5.0) он работает нормально независимо от настроек оптимизации.
Комментирование сравнения с глобальной строкой также позволяет избежать сбоя.
Может ли кто-нибудь увидеть какие-либо проблемы с моим кодом? Если нет, то есть какие-нибудь теории о причине крушения? Возможно, новая оптимизация LLVM вызывает ошибку в среде выполнения libstdc++ в iOS 5.1?
Другой вариант, о котором я могу думать, заключается в том, что оптимизатор генерирует недопустимый код. Это было бы гораздо большим беспокойством.