Otomatik oluşturma dönüş kodu denetleyicisi aracı

Başka bir altprogramın dönüş kodunu kontrol etmek için altprogram üreten bir araç arıyorum.

Örneğin, pthread_create , 0 , EAGAIN , EINVAL ve EPERM kodlarını döndürür. Böyle bir denetleyiciye sahip olmak güzel olurdu:

void pthread_create_check(int retcode) {
    switch (retcode) {
    case 0:
        printf("pthread_create success.\n");
        break;
    case EAGAIN:
        printf("pthread_create EAGAIN error: insufficient resources"
               " to create another thread, or a system-imposed"
               " limit on the number of threads was encountered.\n");
        break;
    case EINVAL:
        printf("pthread_create EINVAL error: invalid settings in"
               " attr.\n");
        break;
    case EPERM:
        printf("pthread_create EPERM error: no permission to set the"
               " scheduling policy and parameters specified in"
               " attr.\n");
        break;
    }
}

Ve böyle bir şekilde kullanın:

iret = pthread_create(&thread_desc, 
                      NULL, 
                      thread_function, 
                      (void *) thread_param);
pthread_create_check(iret);

Man sayfasındaki her hata kodunun açıklaması vardır. Böyle bir denetleyici oluşturmak, kopyala yapıştır hata kodlarından ve man sayfasından açıklamadan başka bir şey değildir. Bilgisayarın bu işi insandan çok daha iyi yapabileceğini düşünüyorum çünkü bilgisayar asla lastiği almıyor. Ayrıca, her bir alt program için bunu yapmak için çok tembelim. Herhangi bir otomasyon aracı var mı?

0
lütfen açıklayın: man sayfasından herhangi bir kütüphane çağrısı için bir iade kodu denetleyicisi oluşturan genel kod üretecini mi istediğinizi kastediyorsunuz? (_Bu durumda (a) iyi şanslar (b) en iyi tavsiyem, çalışma zamanında çağrıları kesmek için harika ptrace sistem çağrısı olacaktır.
katma yazar sehe, kaynak
Bu imkansız değil, ama pratik olmaktan çok uzak. Nedeni, man sayfalarında hata kodları için standart bir formatlama olmamasıdır. Bu sayfalar, makineler tarafından değil, insanlar tarafından okunması için tasarlanmıştır, bu yüzden kesinlikle kontrol edilmezler. Ayrıca, bir hata mesajında ​​görmek istediğiniz ifadeyle aynı değildir. Elbette, IBM'in Watson gibi bir şeye erişiminiz varsa, bir çekiminiz olabilir.
katma yazar Mike DeSimone, kaynak
Evet, kod üreticisi istiyorum. Ortak alt rutinleri anlayan jenerik olmayan jeneratörle bile memnun olacağım, ör. fopen , mq_send . Neden imkansız olduğunu düşünüyorsun?
katma yazar Kirill, kaynak

2 cevap

Sadece mesaj tabloları yap. Kodlama zamanını ve alanını koruyacaktır.

typedef struct pthread_message {
    int code;
    const char* text;
} pthread_message;

int pthread_check(int retcode, const char* fname, 
    pthread_message* messages)
{
    if(!retcode) /* Makes the common case fast. */
    {
        fprintf(stderr, "%s success.\n", fname);
        return retcode;
    }

    /* Look for a message. */
    for(; messages->code; ++messages)
        if(messages->code == retcode)
        {
            fprintf(stderr, "%s %s\n", fname, message->text);
            return retcode;
        }

    /* Fall back on standard library. If you lack strerror_r, 
       then put a generic message here.
    */
    char buf[256];
    fprintf(stderr, "%s %s\n", fname, strerror_r(retcode, buf, 256));
    return retcode;
);

pthread_message pthread_create_messages[] = {
    { EAGAIN, "EAGAIN error: insufficient resources to create another thread,"
      " or a system-imposed limit on the number of threads was encountered." },
    { EINVAL, "EINVAL error: invalid settings in attr." },
    { EPERM, "EPERM error: no permission to set the scheduling policy and"
      " parameters specified in attr." },
    { 0, 0 } /* End of list. */
};

iret = pthread_check(pthread_create(arg1, arg2, ...), "pthread_create", 
    pthread_create_messages);

Mesaj listelerini fonksiyonlar arasında paylaşmanın sizi durduran hiçbir şey yok, böylece istediğiniz kadar az veya çok yazabilirsiniz.

Çıldırıyorsanız, çağrıdan bir makro oluşturabilirsiniz:

#define PTHREAD_CHECK(fname, arglist) \
    (pthread_check(fname arglist, #fname, fname##_messages))

iret = PTHREAD_CHECK(pthread_create, (arg1, arg2, ...));

Bu durumda, bir mesaj listesini paylaşmak, ilk fonksiyonun listesine işaret eden her ek fonksiyon için uygun isme sahip bir işaretçi oluşturmanız gerektiği anlamına gelir. Hala çok daha az iş.

Kayıt için, jenerik mesajlarla bir kontrol fonksiyonu yazdım (başarı mesajları hariç, spam oluyorlar) ve pthread'deki C ++ ambalajında ​​her yerde kullandım. (Boost hakkında bana sıkma, bu on yıl önceydi.)

2
katma
Böyle bir aracı mümkün kılmak için man sayfalarının biçimlendirilmesinde neredeyse yeterli tutarlılık yoktur. İyi biçimlenmiş girdilerin ayrıştırılması kendi başına çok fazla iştir; tuhaflıklarla başa çıkmak için tüm kodu eklemek, projeye çok daha fazla çaba harcamanızı ve mesajların kopyalanmasını ve yapıştırılmasını ve yukarıdaki gibi tablo oluşturmanızı gerektirecektir. Gerçek hayatta, olağan durum, hata kodlarını görmezden gelir ve en iyisi için (BAD!), Ardından sıfırdan ve isteğe bağlı olarak strerror 'ı çağırmayı izler. Bazen, başarısız çağrının kodda olduğunu bildirmek için __ FILE __ ve __ LINE __ kullanan bir makro yaparlar.
katma yazar Mike DeSimone, kaynak
DR: DR: Bu, gerçek hayatta çok uğraşan programcılardan çok daha fazla çaba harcıyorsunuz, bu yüzden overboard'la uğraşmaktan, tüm zamanınızı hata işlemek için harcamaktan ve gerçek uygulamayı kodlamadan endişelenmekten endişe ediyorum. Denge ara.
katma yazar Mike DeSimone, kaynak
Çok ilginç bir yaklaşım! Bu iş miktarını azaltır, ancak hala birçok rutin var. Profiliniz çok deneyimli C ++ geliştiriciniz olduğunu söylüyor. Man sayfalarından damağı üreten araç hakkında ne düşünüyorsunuz? Yardımcı olur mu Gerçek hayattaki kodlamada hangi yaklaşım kullanılır?
katma yazar Kirill, kaynak
Cevap ve yorumlarınız için teşekkür ederiz! Deneyimli bir kişinin görüşü vazgeçilmezdir.
katma yazar Kirill, kaynak

Valgrind'in Helgrind'i, POSIX pthreads API'sinin kötüye kullanımını tespit edebilir.

http://valgrind.org/docs/manual/hg -manual.html # hg-manual.api-çekler

1
katma
Hm, Valgrind güçlü bir araçtır. Diğer ortak alt programlar için benzer işlevlere sahiptir, ör. Fopen ?
katma yazar Kirill, kaynak