Задача состоит в том, чтобы читать пакеты из одного трассировщика и писать во многие.
Я использую libtrace_out_t ** для выходных трассировщиков.
Инициализация:
uint16_t size = 10;
libtrace_out_t** array = libtrace_out_t*[size];
for(uint16_t i = 0; i < size; ++i) {
array[i] = trace_create_output(uri); // created OK
trace_start_output(outTracers_[i]); // started OK
}
// writing packets
Создание, запуск и запись пакетов с использованием элементов массива трассировщика — это хорошо.
Проблемы вызваны trace_destroy_output (), когда я уничтожаю выходные трассировщики в цикле:
for(uint16_t i = 0; i < size; ++i)
{
if(outTracers_[i])
trace_destroy_output(outTracers_[i]);
}
На первой итерации вывод трассировщика уничтожается нормально.
Но на втором он терпит неудачу с ошибкой сегментации в
pcap_close(pcap_t* p)
потому что указатель p имеет значение 0x0.
Может кто-нибудь объяснить мне, почему это происходит или как правильно его уничтожить?
Из кода, который вы опубликовали, похоже, что вы создаете 10 выходных трасс, используя один и тот же URI. Итак, по сути, вы создали 10 выходных файлов с одним и тем же именем, что, вероятно, не то, что вы хотели.
Когда приходит время уничтожить выходные трассировки, первое уничтожение закрывает файл, соответствующий указанному вами имени, и устанавливает для ссылки на этот файл значение NULL. Поскольку ссылка теперь имеет значение NULL, любые последующие попытки уничтожить этот файл вызовут ошибку сегментации.
Убедитесь, что вы меняете свой URI для каждой новой выходной трассы, которую вы создаете, и вы должны решить эту проблему.
Пример:
/* I prefer pcapfile: over pcap: */
const char *base="pcapfile:output";
uint16_t size = 10;
libtrace_out_t* array[size];
for (uint16_t i = 0; i < size; ++i) {
char myuri[1024];
/* First output file will be called output-1.pcap
* Second output file will be called output-2.pcap
* And so on...
*/
snprintf(myuri, 1023, "%s-%u.pcap", base, i);
array[i] = trace_create_output(uri);
/* TODO Check for errors here */
if (trace_start_output(array[i])) {
/* TODO Handle error case */
}
}
Еще одна подсказка: libtrace уже включает в себя инструмент под названием tracesplit, который берет входной источник и разбивает пакеты на несколько выходных трасс на основе определенных критериев (например, количество пакетов, размер выходного файла, временной интервал). Этот инструмент может уже делать то, что вы хотите, без необходимости писать код, или, по крайней мере, он будет хорошим примером при написании вашего собственного кода.
Я думаю, что у вас есть доступ за пределами вашего кода
uint16_t size = 5; /// number of tracers
for(uint16_t i = 0; i != size; ++i)
{
if(outTracers_[i])
trace_destroy_output(outTracers_[i]);
}
переводит на
for(uint16_t i = 0; i <= 5; ++i)
{
...
}
И outTracers_ [5] не является допустимым элементом в вашем массиве