0

私を助けようとしているすべての人に事前に感謝します。ここで大きな問題が発生しています。sysctlに関するサンプルコードをいくつか見つけて拡張し、ネットワークインターフェイスに入力/出力データを照会できるようにしました。このコードをmain()で直接(NSAutoreleasePoolなしで)実行すると、すべてが正常に機能します。ただし、クラスに追加して実行すると、バスエラーとsegfaultが発生します。NSAutoreleasePoolsまで問題を追跡しました。誰か助けてもらえますか?(信じられない場合は、NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];をコードの前に配置し、すべてをmain()に配置してください)

int mib[] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 };

    int alloc;

    struct if_msghdr    *ifm, *nextifm;
    struct sockaddr_dl  *sdl;
    char        *lim, *next;
    size_t      needed;
    char        s[32];

    char* buf;
    if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
        return 0;

    if (alloc < needed) {
        buf = malloc(needed);
        if (buf == NULL)
            return 0;
        alloc = needed;
    }

    if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
        return 0;
    lim = buf + needed;

    next = buf;
    while (next < lim) {
        ifm = (struct if_msghdr *)next;

        if (ifm->ifm_type != RTM_IFINFO)
            return 0;
        next += ifm->ifm_msglen;

        while (next < lim) {
            nextifm = (struct if_msghdr *)next;
            if (nextifm->ifm_type != RTM_NEWADDR)
                break;
            next += nextifm->ifm_msglen;
        }        

        if (ifm != NULL && ifm->ifm_flags & IFF_UP) {
            sdl = (struct sockaddr_dl *)(ifm + 1);
            if (sdl->sdl_family != AF_LINK)
                continue;
            strncpy(s, sdl->sdl_data, sdl->sdl_nlen);
            s[sdl->sdl_nlen] = '\0';
            NSLog(@"interface %s in %qu out %qu \n", s,(UInt64)ifm->ifm_data.ifi_ibytes, (UInt64)ifm->ifm_data.ifi_obytes );
        }
    }
4

2 に答える 2

3

それNSAutoreleasePoolは問題ではありません。メモリ割り当て、二重解放、ダングリング ポインター、または初期化されていないデータに問題があることが明らかになります。

あなたの場合、それは初期化されていないデータです。alloc変数を初期化しません。結果として、buf割り当てられているか、ランダムなメモリ位置を指しているかは完全にランダムです。

于 2011-03-27T20:03:39.713 に答える
1

私の推測では、それはあなたの の誤用に関係していますstrncpy()sdl->sdl_nlen文字をコピーしています。これが 32 より大きい場合は、バッファがオーバーフローしています。正確に 32 の場合、 の割り当て\0は の外にありますs[](おそらく 内buf)。

どちらの場合でも、ある種の不正なメモリを に渡しているためNSLog()、それ自体が自動解放された変数を生成します。それらの 1 つが、プールが空になったときのクラッシュの原因である可能性があります。

于 2011-03-27T20:08:28.253 に答える