:
У меня возникли проблемы с преобразованием json в dataframe / CSV. Для моего случая я сделал:
Token <- "245432532532"
source <- "http://......."
header_type <- "applcation/json"
full_token <- paste0("Bearer ", Token)
response <- GET(n_source, add_headers(Authorization = full_token, Accept = h_type), timeout(120), verbose())
text_json <- content(response, type = 'text', encoding = "UTF-8")
jfile <- fromJSON(text_json)
df <- as.data.frame(jfile)
, затем от df до csv.
В этом формате должно быть легко преобразовать его в несколько CSV, если это необходимо.
Важной частью функции контента должно быть type = 'text'
.
Для Linux и я верю Mac OS X, если Вы используете gcc или какой-либо компилятор, который использует glibc, можно использовать след () функции в execinfo.h
, чтобы распечатать stacktrace и выйти корректно, когда Вы получаете отказ сегментации. Документация может быть найдена в libc руководстве .
, Вот пример программы, который устанавливает SIGSEGV
обработчик и печатает stacktrace к stderr
когда он segfaults. Эти baz()
функция здесь вызывает segfault, который инициировал обработчик:
#include <stdio.h>
#include <execinfo.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
void handler(int sig) {
void *array[10];
size_t size;
// get void*'s for all entries on the stack
size = backtrace(array, 10);
// print out all the frames to stderr
fprintf(stderr, "Error: signal %d:\n", sig);
backtrace_symbols_fd(array, size, STDERR_FILENO);
exit(1);
}
void baz() {
int *foo = (int*)-1; // make a bad pointer
printf("%d\n", *foo); // causes segfault
}
void bar() { baz(); }
void foo() { bar(); }
int main(int argc, char **argv) {
signal(SIGSEGV, handler); // install our handler
foo(); // this will call foo, bar, and baz. baz segfaults.
}
Компиляция с -g -rdynamic
получает Вас информация о символе в Вашем выводе, который glibc может использовать для создания хорошего stacktrace:
$ gcc -g -rdynamic ./test.c -o test
Выполнение этого получает Вас этот вывод:
$ ./test
Error: signal 11:
./test(handler+0x19)[0x400911]
/lib64/tls/libc.so.6[0x3a9b92e380]
./test(baz+0x14)[0x400962]
./test(bar+0xe)[0x400983]
./test(foo+0xe)[0x400993]
./test(main+0x28)[0x4009bd]
/lib64/tls/libc.so.6(__libc_start_main+0xdb)[0x3a9b91c4bb]
./test[0x40086a]
Это показывает загрузочный модуль, смещение и функцию, что каждый кадр в стеке прибыл из. Здесь Вы видите обработчик сигналов сверху стека и функции libc прежде main
в дополнение к main
, foo
, bar
, и baz
.
Посмотрите средство Отслеживания стека в (адаптивная коммуникационная среда) ACE . Это уже записано для покрытия всех основных платформ (и больше). Библиотека является BSD-стилем, лицензируемым, таким образом, Вы можете даже скопировать/вставить код, если Вы не хотите использовать ACE.
Могло бы стоить посмотреть Google Breakpad , межплатформенный генератор дампа катастрофического отказа и инструменты для обработки дампов.
Ive, смотря на эту проблему некоторое время.
И проложенный под землей глубоко в Google Performance Tools README
http://code.google.com/p/google-perftools/source/browse/trunk/README
переговоры о libunwind
http://www.nongnu.org/libunwind/
Хотели бы услышать мнения этой библиотеки.
проблема с-rdynamic состоит в том, что он может увеличить размер двоичного файла относительно значительно в некоторых случаях
Некоторые версии libc содержат функции то соглашение с отслеживаниями стека; Вы могли бы быть в состоянии использовать их:
http://www.gnu.org/software/libc/manual/html_node/Backtraces.html
я не забываю использовать libunwind давным-давно для получения отслеживаний стека, но он не может поддерживаться на платформе.
Посмотрите на:
человек 3 следа
И:
#include <exeinfo.h>
int backtrace(void **buffer, int size);
Это расширения GNU.
Вы не определили свою операционную систему, таким образом, на это трудно ответить. При использовании системы на основе гну libc Вы могли бы быть в состоянии использовать функцию libc backtrace()
.
GCC также имеет два builtins, которые могут помочь Вам, но которые могут или не могут быть реализованы полностью на Вашей архитектуре, и те __builtin_frame_address
и __builtin_return_address
. Оба из которых хотят непосредственный целочисленный уровень (непосредственным, я имею в виду, это не может быть переменная). Если __builtin_frame_address
для данного уровня является ненулевым, должно быть безопасно захватить обратный адрес того же уровня.
ulimit -c unlimited
системная переменная, которая позволит создавать дамп ядра после Ваших сбоев приложения. В этом случае неограниченная сумма. Ищите файл, названный ядром в том же самом каталоге. Удостоверьтесь, что Вы скомпилировали свой код с включенными отладочными информациями!
отношения
Важно отметить что, как только Вы генерируете базовый файл, необходимо будет использовать gdb инструмент для рассмотрения его. Для gdb для понимания базового файла необходимо сказать gcc оснащать двоичный файл с отладочной информацией: чтобы сделать это, Вы компилируете с флагом-g:
$ g++ -g prog.cpp -o prog
Затем можно или установить "ulimit-c неограниченный", чтобы позволить ему вывести ядро, или просто запустить программу внутри gdb. Мне нравится второй подход больше:
$ gdb ./prog
... gdb startup output ...
(gdb) run
... program runs and crashes ...
(gdb) where
... gdb outputs your stack trace ...
я надеюсь, что это помогает.
победа: как насчет StackWalk64 http://msdn.microsoft.com/en-us/library/ms680650.aspx
Я забыл о технологии GNOME "apport", но я не знаю много об использовании его. Это используется для генерации stacktraces и другой диагностики для обработки и может автоматически зарегистрировать ошибки. К этому, конечно, стоит зарегистрироваться.
intN_t
(как расширение C90) позволило дополнять, таким образом, у Вас могло быть 72-разрядное int64_t
из которых 8 битов используются для дополнения.
–
16 February 2012 в 20:27
ulimit -c <value>
устанавливает базовый предел размера файла для Unix. По умолчанию базовый предел размера файла 0. Вы видите Ваш ulimit
значения с ulimit -a
.
также, если Вы запускаете свою программу из gdb, она остановит Вашу программу на "нарушениях сегментации" (SIGSEGV
, обычно при доступе к части памяти, которую Вы не выделили), или можно установить точки останова.
ddd и nemiver являются фронтендами для gdb, которые делают работу с ним намного легче для новичка.
*nix: можно прервать SIGSEGV (обычно, этот сигнал повышен прежде, чем отказать), и сохраните информацию в файл. (помимо базового файла, который можно использовать для отладки использования gdb, например).
победа: Проверьте это из MSDN.
можно также посмотреть на хромовый код Google, чтобы видеть, как он обрабатывает катастрофические отказы. Это имеет хороший механизм обработки исключений.
Я использовал бы код, который генерирует отслеживание стека для пропущенной памяти в Визуальный Детектор Утечки . Это только работает над Win32, все же.
Я могу помочь с версией Linux: функциональный след, backtrace_symbols и backtrace_symbols_fd может использоваться. См. соответствующие страницы руководства.
На базовых файлах использования Linux/unix/MacOSX (можно включить им с ulimit или совместимый системный вызов ). На сообщении об ошибке Microsoft использования Windows (можно стать партнером и получить доступ к данным сбоя приложения).
Хотя использование функций backtrace () в execinfo.h для печати трассировки стека и корректного выхода при возникновении ошибки сегментации уже предлагалось , Я не вижу упоминания о тонкостях, необходимых для обеспечения того, чтобы результирующая обратная трассировка указывала на фактическое местоположение неисправности (по крайней мере, для некоторых архитектур - x86 и ARM).
Первые две записи в цепочке кадров стека, когда вы попадаете в обработчик сигнала содержит адрес возврата внутри обработчика сигнала и один адрес внутри sigaction () в libc. Фрейм стека последней функции, вызванной перед сигналом (который является местом ошибки), потерян.
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#ifndef __USE_GNU
#define __USE_GNU
#endif
#include <execinfo.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ucontext.h>
#include <unistd.h>
/* This structure mirrors the one found in /usr/include/asm/ucontext.h */
typedef struct _sig_ucontext {
unsigned long uc_flags;
struct ucontext *uc_link;
stack_t uc_stack;
struct sigcontext uc_mcontext;
sigset_t uc_sigmask;
} sig_ucontext_t;
void crit_err_hdlr(int sig_num, siginfo_t * info, void * ucontext)
{
void * array[50];
void * caller_address;
char ** messages;
int size, i;
sig_ucontext_t * uc;
uc = (sig_ucontext_t *)ucontext;
/* Get the address at the time the signal was raised */
#if defined(__i386__) // gcc specific
caller_address = (void *) uc->uc_mcontext.eip; // EIP: x86 specific
#elif defined(__x86_64__) // gcc specific
caller_address = (void *) uc->uc_mcontext.rip; // RIP: x86_64 specific
#else
#error Unsupported architecture. // TODO: Add support for other arch.
#endif
fprintf(stderr, "signal %d (%s), address is %p from %p\n",
sig_num, strsignal(sig_num), info->si_addr,
(void *)caller_address);
size = backtrace(array, 50);
/* overwrite sigaction with caller's address */
array[1] = caller_address;
messages = backtrace_symbols(array, size);
/* skip first stack frame (points here) */
for (i = 1; i < size && messages != NULL; ++i)
{
fprintf(stderr, "[bt]: (%d) %s\n", i, messages[i]);
}
free(messages);
exit(EXIT_FAILURE);
}
int crash()
{
char * p = NULL;
*p = 0;
return 0;
}
int foo4()
{
crash();
return 0;
}
int foo3()
{
foo4();
return 0;
}
int foo2()
{
foo3();
return 0;
}
int foo1()
{
foo2();
return 0;
}
int main(int argc, char ** argv)
{
struct sigaction sigact;
sigact.sa_sigaction = crit_err_hdlr;
sigact.sa_flags = SA_RESTART | SA_SIGINFO;
if (sigaction(SIGSEGV, &sigact, (struct sigaction *)NULL) != 0)
{
fprintf(stderr, "error setting signal handler for %d (%s)\n",
SIGSEGV, strsignal(SIGSEGV));
exit(EXIT_FAILURE);
}
foo1();
exit(EXIT_SUCCESS);
}
signal 11 (Segmentation fault), address is (nil) from 0x8c50
[bt]: (1) ./test(crash+0x24) [0x8c50]
[bt]: (2) ./test(foo4+0x10) [0x8c70]
[bt]: (3) ./test(foo3+0x10) [0x8c8c]
[bt]: (4) ./test(foo2+0x10) [0x8ca8]
[bt]: (5) ./test(foo1+0x10) [0x8cc4]
[bt]: (6) ./test(main+0x74) [0x8d44]
[bt]: (7) /lib/libc.so.6(__libc_start_main+0xa8) [0x40032e44]
Все опасности вызова функций backtrace () в обработчике сигналов все еще существуют и не следует упускать из виду, но я считаю, что описанные здесь функциональные возможности весьма полезны при отладке сбоев.
Важно отметить, что приведенный мной пример разработан / протестирован в Linux для x86. Я также успешно реализовал это в ARM, используя uc_mcontext.arm_pc
вместо uc_mcontext.eip
.
Вот ссылка на статью, в которой я узнал подробности этой реализации: http://www.linuxjournal.com/article/6391
Хотя был предоставлен правильный ответ , который описывает, как использовать GNU libc backtrace ()
функцию 1 , и я предоставил свой собственный ответ , который описывает, как гарантировать, что обратная трассировка от обработчика сигнала указывает на фактическое местоположение неисправности 2 , я не вижу никаких упоминаний о разметке символов C ++, выводимых из след.
При получении трассировки из программы на C ++ вывод можно запустить через c ++ filter
1 , чтобы распутать символы, или с помощью abi :: __ cxa_demangle
1 напрямую.
c ++ filter
и __ cxa_demangle
относятся к GCC В следующем примере C ++ Linux используется тот же обработчик сигнала, что и в моем другом ответе , и демонстрируется, как c ++ filter
можно использовать для распутывания символов.
Код :
class foo
{
public:
foo() { foo1(); }
private:
void foo1() { foo2(); }
void foo2() { foo3(); }
void foo3() { foo4(); }
void foo4() { crash(); }
void crash() { char * p = NULL; *p = 0; }
};
int main(int argc, char ** argv)
{
// Setup signal handler for SIGSEGV
...
foo * f = new foo();
return 0;
}
Вывод ( ./ test
):
signal 11 (Segmentation fault), address is (nil) from 0x8048e07
[bt]: (1) ./test(crash__3foo+0x13) [0x8048e07]
[bt]: (2) ./test(foo4__3foo+0x12) [0x8048dee]
[bt]: (3) ./test(foo3__3foo+0x12) [0x8048dd6]
[bt]: (4) ./test(foo2__3foo+0x12) [0x8048dbe]
[bt]: (5) ./test(foo1__3foo+0x12) [0x8048da6]
[bt]: (6) ./test(__3foo+0x12) [0x8048d8e]
[bt]: (7) ./test(main+0xe0) [0x8048d18]
[bt]: (8) ./test(__libc_start_main+0x95) [0x42017589]
[bt]: (9) ./test(__register_frame_info+0x3d) [0x8048981]
Вывод без запутывания ( ./ test 2> & 1 | c ++ filter
):
signal 11 (Segmentation fault), address is (nil) from 0x8048e07
[bt]: (1) ./test(foo::crash(void)+0x13) [0x8048e07]
[bt]: (2) ./test(foo::foo4(void)+0x12) [0x8048dee]
[bt]: (3) ./test(foo::foo3(void)+0x12) [0x8048dd6]
[bt]: (4) ./test(foo::foo2(void)+0x12) [0x8048dbe]
[bt]: (5) ./test(foo::foo1(void)+0x12) [0x8048da6]
[bt]: (6) ./test(foo::foo(void)+0x12) [0x8048d8e]
[bt]: (7) ./test(main+0xe0) [0x8048d18]
[bt]: (8) ./test(__libc_start_main+0x95) [0x42017589]
[bt]: (9) ./test(__register_frame_info+0x3d) [0x8048981]
Следующее построено на обработчике сигнала из моего исходного ответа и может заменить обработчик сигнала в приведенном выше примере, чтобы продемонстрировать, как abi :: __ cxa_demangle
может быть используется для распутывания символов. Этот обработчик сигнала производит такой же разобранный вывод, что и в приведенном выше примере.
Код :
void crit_err_hdlr(int sig_num, siginfo_t * info, void * ucontext)
{
sig_ucontext_t * uc = (sig_ucontext_t *)ucontext;
void * caller_address = (void *) uc->uc_mcontext.eip; // x86 specific
std::cerr << "signal " << sig_num
<< " (" << strsignal(sig_num) << "), address is "
<< info->si_addr << " from " << caller_address
<< std::endl << std::endl;
void * array[50];
int size = backtrace(array, 50);
array[1] = caller_address;
char ** messages = backtrace_symbols(array, size);
// skip first stack frame (points here)
for (int i = 1; i < size && messages != NULL; ++i)
{
char *mangled_name = 0, *offset_begin = 0, *offset_end = 0;
// find parantheses and +address offset surrounding mangled name
for (char *p = messages[i]; *p; ++p)
{
if (*p == '(')
{
mangled_name = p;
}
else if (*p == '+')
{
offset_begin = p;
}
else if (*p == ')')
{
offset_end = p;
break;
}
}
// if the line could be processed, attempt to demangle the symbol
if (mangled_name && offset_begin && offset_end &&
mangled_name < offset_begin)
{
*mangled_name++ = '\0';
*offset_begin++ = '\0';
*offset_end++ = '\0';
int status;
char * real_name = abi::__cxa_demangle(mangled_name, 0, 0, &status);
// if demangling is successful, output the demangled function name
if (status == 0)
{
std::cerr << "[bt]: (" << i << ") " << messages[i] << " : "
<< real_name << "+" << offset_begin << offset_end
<< std::endl;
}
// otherwise, output the mangled function name
else
{
std::cerr << "[bt]: (" << i << ") " << messages[i] << " : "
<< mangled_name << "+" << offset_begin << offset_end
<< std::endl;
}
free(real_name);
}
// otherwise, print the whole line
else
{
std::cerr << "[bt]: (" << i << ") " << messages[i] << std::endl;
}
}
std::cerr << std::endl;
free(messages);
exit(EXIT_FAILURE);
}
onPause()
и возвращается сonResume()
, загрузчик уведомляется и будет звонитьonStartLoading()
снова. ТакtakeContentChanged()
(еслиonContentChanged()
был назван ранее) вызовет для обновленияmCursor
с последними доступными изменениями. Однако на первомif
I' d помещенный вместо этогоif (mCursor != null && !takeContentChanged())
. – AxeEffect 23 February 2014 в 17:05