如何控制 glib 中调试信息的级别?

Posted

技术标签:

【中文标题】如何控制 glib 中调试信息的级别?【英文标题】:How to control level of debugging info in glib? 【发布时间】:2011-11-23 00:49:30 【问题描述】:

我有一个用 C 语言编写的带有 glib/gobject 的库。它通过g_debug() 调用产生大量调试信息。此信息对故障排除非常有帮助,但是当库包含在实际应用程序中时,我不希望显示它。所以,基本上我需要一种方法来控制/过滤调试信息的数量,但我无法弄清楚它应该如何与 glib 一起工作。请有人指出我正确的方向吗?

【问题讨论】:

【参考方案1】:

您可以尝试设置G_DEBUG 环境变量,如GLib 开发者网站中所述。请参阅http://developer.gnome.org/glib/2.28/glib-running.htmlRunning and debugging GLib Applications 下的Environment variable 部分。

编辑:更新以在代码中设置记录器。 您可以在代码中使用 g_log_set_handler ( http://developer.gnome.org/glib/2.29/glib-Message-Logging.html#g-log-set-handler ) 来执行此操作。最初,您可以将日志处理程序设置为不显示任何内容的虚拟函数,然后您可以根据为设置适当的日志级别传递的参数将日志处理程序设置为g_log_default_handler。要将日志级别设置为高于设定级别,您需要根据需要操作 GLogLevelFlags 值。 希望下面的代码示例能提供一些指导

#include <glib.h>
#include <stdio.h>
#include <string.h>

#define G_LOG_DOMAIN    ((gchar*) 0)

static void _dummy(const gchar *log_domain,
                     GLogLevelFlags log_level,
                     const gchar *message,
                     gpointer user_data )


  /* Dummy does nothing */ 
  return ;      


int main(int argc, char **argv)

    /* Set dummy for all levels */
    g_log_set_handler(G_LOG_DOMAIN, G_LOG_LEVEL_MASK, _dummy, NULL);
    /* Set default handler based on argument for appropriate log level */
    if ( argc > 1)
    
         /* If -vv passed set to ONLY debug */
         if(!strncmp("-vv", argv[1], 3))
         
            g_log_set_handler(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,  g_log_default_handler, NULL);
         
         /* If -v passed set to ONLY info */
         else if(!strncmp("-v", argv[1], 2))
         
             g_log_set_handler(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, g_log_default_handler, NULL);
         
        /* For everything else, set to back to default*/
         else
         
              g_log_set_handler(G_LOG_DOMAIN, G_LOG_LEVEL_MASK, g_log_default_handler, NULL);
         

    
    else /* If no arguments then set to ONLY warning & critical levels */
    
        g_log_set_handler(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING| G_LOG_LEVEL_CRITICAL, g_log_default_handler, NULL);
    

    g_warning("This is warning\n");
    g_message("This is message\n");
    g_debug("This is debug\n");
    g_critical("This is critical\n");
    g_log(NULL, G_LOG_LEVEL_INFO , "This is info\n");
    return 0;

希望这会有所帮助!

【讨论】:

这不是我想要的。我希望能够通过 -v 只显示 INFO 及以上消息,并且 -vv 还包括调试。如果未提供任何参数,则仅显示 WARNING 和 CRITICAL。基本上,我正在寻找的是一种从应用程序内部控制它的方法。据我了解,G_DEBUG 环境变量有不同的用途。 谢谢@another.anon.coward。我现在才注意到您的编辑,这正是我正在寻找的答案。好吧,这次我自己也做了同样的事情,但还是谢谢你 ;-)【参考方案2】:

我实现了自定义日志处理程序,结果如下:

void custom_log_handler (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data)

    gint debug_level = GPOINTER_TO_INT (user_data);

    /* filter out messages depending on debugging level */
    if ((log_level & G_LOG_LEVEL_DEBUG) && debug_level < MyLogLevel_DEBUG) 
        return;
    
    else if ((log_level & G_LOG_LEVEL_INFO) && debug_level < MyLogLevel_INFO) 
        return;
    

    g_printf ("%s\n", message);



int main(int argc, char *argv[])

    ...
    if (verbose) 
        g_log_set_handler (NULL, G_LOG_LEVEL_MASK, custom_log_handler, GINT_TO_POINTER (MyLogLevel_DEBUG));
    
    else 
        g_log_set_handler (NULL, G_LOG_LEVEL_MASK, custom_log_handler, GINT_TO_POINTER (MyLogLevel_NORMAL));
    
    ...

我希望它对某人有所帮助:-)

【讨论】:

【参考方案3】:

您可以在运行应用程序时通过设置G_MESSAGES_DEBUG 环境变量来控制是否打印调试(日志)消息。

当您需要打印调试(日志)消息时,最简单的方法是使用$ G_MESSAGES_DEBUG=all ./your-app

但是,当G_MESSAGES_DEBUG=all glib 库本身也会打印您可能不需要的调试(日志)消息时。因此,为您的应用程序预定义G_LOG_DOMAIN 为单独的自定义log domain 字符串,并在运行时将G_MESSAGES_DEBUG 设置为相同的字符串。例如,在编译器标志中使用-DG_LOG_DOMAIN=\"my-app\",并使用$ G_MESSAGES_DEBUG="my-app" ./your-app 运行应用程序。

【讨论】:

以上是关于如何控制 glib 中调试信息的级别?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 CMake 启用 gdb -g3 调试级别?

如何禁用tomcat 7控制台调试信息

Logcat的级别以及Logcat的调试使用

第十章 心得体会

添加增强调试器以查看基于 Smack android 的 XMPP 客户端的数据包级别信息

Xcode:无法为调试设置优化级别