SystemTap, кажется, дает нерелевантный вывод

Моя система — Ubuntu, uname -r = 4.15.0-23-generic. Я установил символы отладки для ядра.

Моя проблема:


Я пытаюсь использовать socket(AF_PACKET, SOCK_DGRAM, 0) для целей передачи. Для системного вызова sendto(fd, 0,0,0,0,0) у меня есть EINVAL (недопустимый аргумент), и я пытаюсь выяснить причину.


Поэтому, чтобы узнать, что возвращает EINVAL, я использую SystemTap. Сценарий ниже отслеживает оператор выполнения по оператору функции tpacket_snd.

моя тестовая программа: info.stp

probe kernel.statement("tpacket_snd@*:*") {
    tokenize(pp(),"@");
    printf("HIT %s\n", tokenize("","@"))
}

А вот вывод sudo stap info.stp для моей реализации такой передачи:

HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2619")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2627")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2628")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2636")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2638")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2640")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2641")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2656")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2659")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2658")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2662")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2663")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2669")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2671")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2674")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2672")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2675")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2680")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2688")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2692")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2694")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2693")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2706")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2710")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2707")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2708")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2709")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2712")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2743")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2728")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2736")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2735")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2785")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2787")
HIT /build/linux-uT8zSN/linux-4.15.0/net/packet/af_packet.c:2789")

[https://elixir.bootlin.com/linux/v4.15/source/net/packet/af_packet.c#L2618]


Мой вопрос: этот вывод не имеет отношения (не соответствует) к исходному коду, потому что:

  1. Во-первых, указано, что строка af_packet.c:2707 была выполнена после того, как 2710 2710 не содержит команды перехода.

  1. Во-вторых, из моего исследования я могу сделать вывод об этом условии: [строки 2741-2745]

    if (po->has_vnet_hdr && virtio_net_hdr_to_skb(skb, vnet_hdr, vio_le())) { tp_len = -EINVAL; перейти к tpacket_error; }

    была оценена как верная — обратите внимание, что SystemTap указывает на то, что строка 2743 была выполнена. Но, с другой стороны, я исследовал с помощью SystemTap, что po->has_vnet_hdr равно 0, поэтому выполнить его невозможно, если body. Однако SystemTap указывает на это.

Мой вопрос:

Как его починить или что я делаю не так?


person Gilgamesz    schedule 12.06.2018    source источник
comment
Моя первоначальная реакция заключалась в том, что это просто вывод компилятора с оптимизацией. Нет никакой гарантии, что базовый порядок ассемблера будет соответствовать исходному коду.   -  person Peter Brittain    schedule 15.06.2018
comment
Для сокетов SOCK_DGRAM вы должны указать адрес назначения для каждого sendto(). Передача NULL, 0 для адреса, addr_len недействительна.   -  person Iwillnotexist Idonotexist    schedule 22.06.2018


Ответы (1)


Q1: Питер совершенно прав. После оптимизации компилятора строки исходного кода могут выполняться в нелинейной последовательности, поскольку инструкции разных операторов C перемешаны. Это не представляет проблемы.

Q2: Чтобы выяснить, какой оператор вызвал возврат -EINVAL, я бы объединил зонды операторов (как у вас, за исключением того, что вы печатаете $$vars для просмотра локальных переменных) И пару зондов функции .call/.return, чтобы обратите внимание, когда функция оставлена. Последние несколько строк трассировки оператора перед возвратом будут тем местом, где я буду искать причину.

person fche    schedule 03.08.2018