ошибка mudflap при использовании socket ()

#c #gcc #posix

#c #gcc #posix

Вопрос:

При подобной компиляции я получаю следующее нарушение mudflap, и я понятия не имею, что это значит:

(Я использую Debian squeeze, gcc 4.4.5 и eglibc 2.11.2)

mudflap:

мой пользователь @linux: ~/ Desktop$ export MUDFLAP_OPTIONS="-проверка режима -нарушение-прерывание -внутренней-проверки -утечек -печати -проверка-инициализации -подробных-нарушений -зоны свертывания = 32"
мой пользователь @linux: ~/Desktop $ gcc -std=c99 -D_POSIX_C_SOURCE=200112L -ggdb3 -O0 -fmudflap -funwind-tables -lmudflap -динамическая моя программа.c 
мой пользователь@linux: ~/Desktop $ ./a.out
*******
нарушение mudflap 1 (проверка / чтение): time = 1303221485.951128 ptr = 0x70cf10 size = 16
pc=0x7fc51c9b1cc1 location=`myprogram.c:22:18 (main)'
 /usr/lib/libmudflap.so.0(__mf_check 0x41) [0x7fc51c9b1cc1]
 ./a.out(main  0x113) [0x400b97]
 /lib/libc.so.6(__libc_start_main 0xfd) [0x7fc51c665c4d]
Соседний объект 1: проверяемая область начинается с 0B и заканчивается на 15B 
объект mudflap 0x70cf90: name=`область malloc' 
границы = [0x70cf10,0x70cf5b] размер = 76 площадь = проверка кучи = 1r / 0w живучесть = 1 
выделенное время = 1303221485.949881 pc = 0x7fc51c9b1431 
 /usr/lib/libmudflap.so.0(__mf_register 0x41) [0x7fc51c9b1431]
 /usr/lib/libmudflap.so.0(__wrap_malloc 0xd2) [0x7fc51c9b2a12]
 /lib/libc.so.6( 0xaada5) [0x7fc51c6f1da5]
 /lib/libc.so.6(getaddrinfo 0x162) [0x7fc51c6f4782]
Соседний объект 2: проверяемая область начинается 640B раньше и заканчивается 625B раньше
неисправный объект mudflap 0x70d3f0: name=`область malloc' 
границы = [0x70d190,0x70d3c7] размер = 568 область = проверка кучи = 0r / 0w живучесть = 0 
время выделения = 1303221485.950059 pc = 0x7fc51c9b1431 
 /usr/lib/libmudflap.so.0(__mf_register 0x41) [0x7fc51c9b1431]
 /usr/lib/libmudflap.so.0(__wrap_malloc 0xd2) [0x7fc51c9b2a12]
 /lib/libc.so.6( 0x6335b) [0x7fc51c6aa35b]
 /lib/libc.so.6( 0xac964) [0x7fc51c6f3964]
время освобождения = 1303221485.950696 pc = 0x7fc51c9b0fe6 
 /usr/lib/libmudflap.so.0(__mf_отменить регистрацию  0x36) [0x7fc51c9b0fe6]
 /usr/lib/libmudflap.so.0(__real_free 0xa0) [0x7fc51c9b2f40]
 /lib/libc.so.6(fclose   0x14d) [0x7fc51c6a9a1d]
 /lib/libc.so.6( 0xacc1a) [0x7fc51c6f3c1a]
количество близлежащих объектов: 2
Прервано (сброс ядра)
мой пользователь@linux: ~/Desktop $

gdb:

(gdb) bt
#0 0x00007fd30f18136e в __libc_waitpid (pid=, stat_loc=0x7fff3689d75c, параметры=) в ../sysdeps/unix/sysv/linux/waitpid.c:32
#1 0x00007fd30f11f299 в do_system (строка=) в ../sysdeps/posix/system.c:149
#2 0x00007fd30f44a9c3 при нарушении __mf_ (ptr=, sz =, pc = 0, location= 0x7fff3689d880 " 360  323p", тип=)
 в ../../../src/libmudflap/mf-runtime.c:2174
#3 0x00007fd30f44ba5d при проверке __mfu_ (ptr=0x70cf10, sz=, тип =, местоположение =)
 в ../../../src/libmudflap/mf-runtime.c:1037
#4 0x00007fd30f44bcc1 в __mf_check (ptr=0x70cf10, sz= 16, type = 0, location=0x400e5a "myprogram.c:22:18 (main)") в ../../../src/libmudflap/mf-runtime.c:816
#5 0x0000000000400b97 в main () в myprogram.c:5
(gdb) bt полный
#0 0x00007fd30f18136e в __libc_waitpid (pid=, stat_loc=0x7fff3689d75c, параметры=) в ../sysdeps/unix/sysv/linux/waitpid.c:32
 oldtype = 
 результат = 
#1 0x00007fd30f11f299 в do_system (строка=) в ../sysdeps/posix/system.c:149
 __result = -512
 _buffer = {__routine = 0x7fd30f11f5f0, __arg = 0x7fff3689d758, __canceltype = 915003406, __prev = 0x7fd30f459348}
 _avail = 0 
 статус = 
 сохранить = 
 pid = 5385
 sa = {__sigaction_handler = {sa_handler = 0x1, sa_sigaction = 0x1}, sa_mask = {__val = {65536, 0 }}, sa_flags = 0, sa_restorer = 0x7fd30f0ec578}
 omask = {__val = {0, 4294967295, 206158430240, 1, 2212816, 0, 140734108391560, 3, 140544470949888, 140544474854386, 140544214827009, 0, 7394247, 140544467453304, 
 140544471045644, 140734108391424}}
#2 0x00007fd30f44a9c3 при нарушении __mf_ (ptr=, sz =, pc = 0, location= 0x7fff3689d880 " 360  323p", тип=)
 в ../../../src/libmudflap/mf-runtime.c:2174 
 buf = "gdb --pid=5384000037317p000000000037737737737700000000(000000000000000100000000000000`306!", '00' , "37 317p000000000020 317p000000000000 D1732317700003622631771732317700000100000037717700000000000000000000340Pp0000000000hHD1732317700"
 номер нарушения = 1
#3 0x00007fd30f44ba5d при проверке __mfu_ (ptr=0x70cf10, sz=, тип =, местоположение =)
 в ../../../src/libmudflap/mf-runtime.c:1037 
 entry_idx = 1 
 запись = 0x604ec0
 оценка = -512
 ptr_high = 140734108391840
 __PRETTY_FUNCTION__ = "__mfu_check"
#4 0x00007fd30f44bcc1 в __mf_check (ptr=0x70cf10, sz= 16, type = 0, location=0x400e5a "myprogram.c:22:18 (main)") в ../../../src/libmudflap/mf-runtime.c:816
 __PRETTY_FUNCTION__ = "__mf_check"
#5 0x0000000000400b97 в main () в myprogram.c:5
 подсказки = {ai_flags = 0, ai_family = 0, ai_socktype = 1, ai_protocol = 6, ai_addrlen = 0, ai_addr = 0x0, ai_canonname = 0x0, ai_next = 0x0}
 результат = 0x70cf10 
 newsocket = 0 
(gdb) завершение работы

исходный код:

 
#include "stdio.h" // quotes inserted instead of usual chars for correct website view
#include "sys/socket.h"
#include "netdb.h"

int main(void)
{
    struct addrinfo hints, *result;
    hints.ai_flags      = 0;
    hints.ai_family     = AF_UNSPEC;
    hints.ai_socktype   = SOCK_STREAM;
    hints.ai_protocol   = IPPROTO_TCP;
    hints.ai_addrlen    = 0;
    hints.ai_canonname  = NULL;
    hints.ai_addr       = NULL;
    hints.ai_next       = NULL;

    if(getaddrinfo("localhost", "25", amp;hints, amp;result) != 0)
    {
        return -1;
    }

    int newsocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); // line 22
    if(newsocket == -1)
    {
        freeaddrinfo(result);
        return -2;
    }

    return 0;
}
  

Ответ №1:

Похоже, что он жалуется на чтение неинициализированных данных («нарушение mudflap 1 (проверка / чтение)»). Похоже, что рядом с ошибочным адресом есть пара известных областей. Одна из областей, расположенных немного дальше («проверенная область начинается на 640 Б раньше и заканчивается на 625 Б раньше»), уже освобождена («неисправный объект mudflap»). Другая на самом деле начинается в том же месте, что и неверное чтение («проверенная область начинается с 0B и заканчивается 15B в объекте mudflap 0x70cf90: name =`malloc region'»).

Почему бы вам не установить -viol-gdb в MUDFLAP_OPTIONS и не использовать GDB для проверки ошибочного кода?

ETA: Нарушение происходит из-за того, что в истории доступа к этому региону указано «check =1r /0w». Это указывает на то, что из него выполняется чтение, но, насколько libmudflap известно, в этот регион никогда не записывалась информация. Таким образом, считывание представляет собой ошибку «использовать до инициализации». Это именно то, для чего предназначен -check-initialization флаг, который вы предоставили libmudflap .

Конечно, проблема просто в том, что ваш libc не инструментирован libmudflap , поэтому, хотя libmudflap он может перехватывать malloc вызов, он не может перехватывать обращения к указателю, которые используются для инициализации памяти. Таким образом, когда ваша программа пытается работать с указателем, это выглядит так, как будто вся ее память была выделена, но в нее никогда не записывалась (на самом деле, к ней вообще никогда не обращались).

Вы можете проигнорировать эту ошибку, удалить -check-initialization , чтобы она перестала помечаться как ошибка, или создать libc инструментальный файл для libmudflap и связать свой исполняемый файл с этой версией libc .

Комментарии:

1. Я добавил вывод gdb, но я все еще не вижу света на то, что может быть не так.

2. Вывод GDB подтверждает, что проблема с памятью связана с result . Я вскоре отредактирую свой ответ с решением.