自动生成返回码检查器的工具

发布于 2024-12-12 18:17:10 字数 1240 浏览 3 评论 0原文

我正在寻找一个生成子例程来检查其他子例程的返回码的工具。

例如,pthread_create 可以返回 0EAGAINEINVALEPERM 代码。如果有这样的检查器就好了:

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;
    }
}

并以这样的方式使用它:

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

手册页中有每个错误代码的解释。创建这样的检查器只不过是复制粘贴错误代码和手册页中的解释。我认为计算机可以比人类更好地完成这项工作,因为计算机永远不会疲劳。另外,我懒得为每个子程序调用都这样做。有没有自动化工具?

I'm looking for a tool which generates subroutine for checking a return code of some other subroutine.

For example, pthread_create can returns 0, EAGAIN, EINVAL and EPERM codes. It would be nice to have such checker:

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;
    }
}

And use it in such manner:

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

There are explanation of each error code in man page. Creating such checker is nothing but copy-paste error codes and explanation from man page. I think that computer can done this job much better than human since computer never get tire. Also, I'm too lazy to do it for every subroutine call. Is there any automation tool?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

自控 2024-12-19 18:17:10

只需制作消息表即可。它将节省编码时间和空间。

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);

没有什么可以阻止您在函数之间共享消息列表,因此您可以根据需要编写任意内容。

如果你疯了,你可以在调用中创建一个宏:

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

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

在这种情况下,共享消息列表意味着你需要为每个附加函数创建一个具有正确名称的指针,指向第一个函数的列表。工作量还是少了很多。

作为记录,我只是编写了一个带有通用消息的检查函数(成功消息除外,它们是垃圾邮件),并在围绕 pthread 的 C++ 包装器中的各处使用了它。 (别对 Boost 吹毛求疵,那是十年前的事了。)

Just make message tables. It will save coding time and space.

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);

There's nothing stopping you from sharing message lists between functions, so you can write as little or as much as you want.

If you're insane, you can make a macro out of the call:

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

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

In this case, to share a message list means you need to create a pointer with the proper name for each additional function pointing to the list of the first function. Still a lot less work.

For the record, I just wrote one check function with generic messages (except for the success messages, they're spammy) and used it everywhere in my C++ wrapper around pthread. (Don't carp at me about Boost, this was ten years ago.)

贪恋 2024-12-19 18:17:10

Valgrind 的 Helgrind 可以检测 POSIX pthreads API 的滥用。

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

Valgrind's Helgrind can detect misuses of the POSIX pthreads API.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文