SORU
20 Mayıs 2013, PAZARTESİ


Arama Bunun sarılmış sinyal ZeroMQ kod işleyicisi

Oldukça iyi iş gibi görünüyor http://www.linux-nantes.org/~fmonnier/ocaml/ocaml-wrapping-c.php, en kılavuzuna göre CZMQ Bunun için bazı bağlantıları yazdım. Örneğin burada zstr_send:

CAMLprim value
caml_zstr_send(value socket_val, value string_val)
{
    CAMLparam2 (socket_val, string_val);

    void *sock = CAML_CZMQ_zsocket_val(socket_val);
    char *string = String_val(string_val);
    int rc = zstr_send(sock, string);

    CAMLreturn (Val_int(rc));
}

Ve mesajları benim kod gayet güzel çoğu bu bağlantıları kullanarak gönderip alabiliyorum. Ancak, gönderir yapmak istediğim bir senaryo var ve ne mesaj geçirme sonuna sinyal işleyicisi içine alır, başka bir kod arka planda. Bu basitleştirilmiş örnek:

open ZMQ
exception SocketBindFailure

let bg_ctx = zctx_new ();;
let pub_sock = zsocket_new bg_ctx ZMQ_PUB;;

let handler _ =
    print_endline "enter handler";
    print_endline (string_of_int (zstr_send pub_sock "hello"));
    print_endline "end handler";
;;

let () =
    (try (
        (* bind pub socket *)
        let rc = zsocket_bind pub_sock "tcp://*:5556" in
        if (rc < 0) then ( raise SocketBindFailure );

        Sys.set_signal 
            Sys.sigalrm
            (Sys.Signal_handle handler);

        ignore
             (Unix.setitimer
                 Unix.ITIMER_REAL
                 { Unix.it_interval = 0.01 ; Unix.it_value = 0.01 });

        (* do some work *)
    )
    with 
    | SocketBindFailure -> raise SocketBindFailure) 
;;

En üst düzey, bu çıkışı ile başarısız:

enter handler
0
end handler
Fatal error: exception Sys_blocked_io

C kod Bunun üzerinde benzer gayet güzel çalışıyor. Bunun bu istisna neden olan denklem ekleme nedir?

CEVAP
24 Temmuz 2014, PERŞEMBE


İki olası sorunları vardır:

Bir sinyal işleyicisi içinde, yalnızca arayabilirsinizasenkron sinyal güvenlifonksiyonlar. Çok fonksiyonu sinyal güvenli uyumsuz değildir.

Kısıtlama nedeni, bir işlevi aynı işlevi yürütme ortasında denilebilir. Böylece, iç durumu bozuk olabilir. Çok az zaman uyumsuz fonksiyonlar sinyal, güvenli ve bellek dinamik olarak tahsis eden bir şey değil. Bunun birçok ayırma "perde arkasında" kod değil, bu yüzden muhtemelen, sinyal uyumsuz güvenli olur.

Senin durumunda, standart çıktıya yazar bir fonksiyonu çağırıyorsunuz. C, buaslazaman uyumsuz sinyal güvenli bir istisna dışında: write() ilkel fonksiyon. Bu çiğ sistem çağrısı (faaliyet gösteren bir tanımlayıcı dosyası) ve bir zaman uyumsuz sinyal güvenli için basit bir nedenle bu çekirdeğin kendisi için fark etmez eğer bir sinyal işleyicisi ve iradeye sahip tamamen temizlenmiş dönmeden önce kontrol etmek.

Sinyali uyumsuz (burada) ve güvensiz bir işlevi kendisi böldü sinyal işleyici, güvensiz bir fonksiyonu çağırıyortanımsız davranışC. Bu demektirher şey olabilirprogramınız düzgün, ama aynı zamanda bölümleme hataları veya diğer hatalar da dahil olmak üzere, çalışma yanı sıra, saldırganın keyfi kod çalıştırmasına izin dahil olmak üzere. Bu normalde C gibi düşük seviyeli diller ile ilişkilidir ve normal olarak Bunun oluşmaz.

Bir sinyal için bir işleyici Bunun ayarlandı alındığında, bir kayıt noktası kadar işleyicisi yürütülürken erteledi. bunun bir hile kullanır: Sonuç işleyici güvenli bir ayarlamak içinKutusuzref bir değişken nicelik. Ancak, print gibi diğer fonksiyonları iç durum olması mümkün değil desteklemeyeceğini. Sinyal işleyicisi içinde genel olarak, bir bayrak ayarı ve derhal iade fazlasını yapmaktan kaçınmaya çalışmalısınız. Bunun içinde, bu bayrak, bu Kutusuz olduğundan 31 - 63 - bit bir tamsayı veya boolean olmalıdır. C, bayrağı ya da volatile sig_atomic_t ya da (bundan emin değilim) C11 atom bir tür olmalıdır.

@TheCodeArtist bu hatanın diğer olası bir neden verir.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Joshua Kywn

    Joshua Kywn

    17 Mayıs 2010
  • Khan Academy

    Khan Academy

    17 Kasım 2006
  • MikeyMacintosh

    MikeyM

    28 Aralık 2009