Еще одна возможная причина этого:
Я видел это в журнале:
Не удалось разрешить атрибут
blockquote>проблема заключалась в том, что я пытался использовать цвет из текущей темы в качестве фона для одного из моих макетов.
, например
android:background="?themeColor"
Изменение этого на определенный цвет устраняло проблему .
android:background="@color/White"
Я думаю, что это - действительно плохая идея.
Мобильность является очень достойной целью, но не, когда она приводит к решению, которое навязчиво, иссушает производительность, и нижняя реализация.
Каждая платформа (Windows/Linux/PS2/iPhone/etc), я продолжил работать, предложила способ обойти стек, когда исключение происходит, и соответствие адресует к именам функций. Да, ни один из них не портативен, но платформа создания отчетов может быть, и обычно требуется меньше чем день или два для записи определенной для платформы версии кода прохода по стеку.
Не только это меньше времени, чем оно взяло бы создание/поддержание межплатформенного решения, но результаты намного лучше;
Искать Nested Diagnostic Context
однажды. Вот немного подсказки:
class NDC {
public:
static NDC* getContextForCurrentThread();
int addEntry(char const* file, unsigned lineNo);
void removeEntry(int key);
void dump(std::ostream& os);
void clear();
};
class Scope {
public:
Scope(char const *file, unsigned lineNo) {
NDC *ctx = NDC::getContextForCurrentThread();
myKey = ctx->addEntry(file,lineNo);
}
~Scope() {
if (!std::uncaught_exception()) {
NDC *ctx = NDC::getContextForCurrentThread();
ctx->removeEntry(myKey);
}
}
private:
int myKey;
};
#define DECLARE_NDC() Scope s__(__FILE__,__LINE__)
void f() {
DECLARE_NDC(); // always declare the scope
// only use try/catch when you want to handle an exception
// and dump the stack
try {
// do stuff in here
} catch (...) {
NDC* ctx = NDC::getContextForCurrentThread();
ctx->dump(std::cerr);
ctx->clear();
}
}
Издержки находятся в реализации NDC. Я играл с лениво оцененной версией, а также той, которая только сохранила постоянное число записей также. Ключевой пункт то, что при использовании конструкторов и деструкторов для обработки стека так, чтобы Вам не были нужны все противные try
/catch
блоки и явное управление везде.
Единственная платформа определенная головная боль getContextForCurrentThread()
метод. Можно использовать платформу определенная реализация с помощью локальной памяти потока для обработки задания в большинстве если не все случаи.
Если Вы - больше производительности, ориентированной и живой в мире файлов журнала, то изменяете объем, чтобы содержать указатель на имя файла и номер строки и опустить вещь NDC в целом:
class Scope {
public:
Scope(char const* f, unsigned l): fileName(f), lineNo(l) {}
~Scope() {
if (std::uncaught_exception()) {
log_error("%s(%u): stack unwind due to exception\n",
fileName, lineNo);
}
}
private:
char const* fileName;
unsigned lineNo;
};
Это даст Вам хорошее отслеживание стека в Вашем файле журнала, когда исключение будет выдано. Никакая потребность в любом реальном проходе по стеку, просто немного сообщения журнала, когда исключение выдается ;)
В отладчике:
Для получения отслеживания стека того, где исключением является бросок от, я просто засовываю точку останова в станд.:: конструктор исключения.
Таким образом, когда исключение создается остановки отладчика, и можно затем видеть отслеживание стека в той точке. Не прекрасный, но это работает большую часть времени.
Я не думаю, что существует "независимый от платформы" способ сделать это - в конце концов, если бы было, то не было бы потребности в StackWalk или специальных функциях трассировки стопки gcc, которые Вы упоминаете.
Это было бы немного грязно, но способ, которым я реализую это, состоял бы в том, чтобы создать класс, который предлагает последовательный интерфейс для доступа к отслеживанию стека, затем имейте #ifdefs в реализации, которые используют соответствующие определенные для платформы методы для фактического соединения отслеживания стека.
Тем путем Ваше использование класса независимо от платформы, и просто что класс должен был бы быть изменен, если бы Вы хотели быть нацеленными на некоторую другую платформу.
Это будет медленнее, но похоже на него, должен работать.
Из того, что я понимаю, что проблема в создании быстрого, портативного, отслеживания стека состоит в том, что реализацией стека является и ОС и конкретный ЦП, таким образом, это - неявно платформа определенная проблема. Альтернатива должна была бы использовать функции MS/glibc и использовать #ifdef, и соответствующий препроцессор определяет (например, _WIN32) для реализации платформы определенные решения в различных сборках.
Так как использование стека является высоко платформой и зависящий от реализации, нет никакого способа сделать это непосредственно, который является абсолютно портативным. Однако Вы могли создать портативный интерфейс на платформу и компилятор определенная реализация, локализовав проблемы как можно больше. По моему скромному мнению, это было бы Вашим лучшим подходом.
Реализация трассировщика затем связалась бы с любой платформой, определенные библиотеки помощника доступны. Это затем работало бы только, когда исключение происходит, и даже затем, только если Вы назвали его от блока выгоды. Его минимальный API просто возвратил бы строку, содержащую целую трассировку.
Требование, чтобы кодер ввел выгоду и обработку переброска в цепочке вызовов, имеет значительные затраты во время выполнения на некоторых платформах и налагает большую будущую стоимость обслуживания.
Тем не менее, если Вы действительно принимаете решение использовать механизм выгоды/броска, не забывайте, что даже C++ все еще имеет препроцессор C в наличии, и что макросы __FILE__
и __LINE__
определяются. Можно использовать их для включения имени исходного файла и номера строки в трассировочной информации.