在分析 VLC源码过程中,最常用的方式是用VLC自带的msg_Dbg(...)函数,但是该函数需要一个存在的对象作为输入,实际在很多函数中没有这样的对象,同时为了了解这样的函数运行过程,因此本文根据VLC提供的调试分析函数进行了简单的修改,使其应用于这样的函数中。
1.在vlc/include/vlc_messages.h中添加如下代码
VLC_API void vlc_Debug(vlc_object_t *, int, const char *, const char *, ...) VLC_FORMAT( 4, 5 ); VLC_API void vlc_vaDebug(vlc_object_t *, int, const char *, const char *, va_list); #define msg_Output(p_this,...) \ vlc_Debug(VLC_OBJECT(p_this), VLC_MSG_DBG, MODULE_STRING, __VA_ARGS__ )2.在vlc/src/misc/messages.c中添加如下代码
void vlc_Debug(vlc_object_t *obj, int type, const char *module, const char *format, ...) { va_list args; va_start (args, format); vlc_vaDebug (obj, type, module, format, args); va_end (args); } static void PrintDebug(int, const msg_item_t *, const char *, va_list); void vlc_vaDebug (vlc_object_t *obj, int type, const char *module, const char *format, va_list args) { // if (obj != NULL && obj->i_flags & OBJECT_FLAGS_QUIET) // return; /* C locale to get error messages in English in the logs */ locale_t c = newlocale (LC_MESSAGES_MASK, "C", (locale_t)0); locale_t locale = uselocale (c); #ifndef __GLIBC__ /* Expand %m to strerror(errno) - only once */ char buf[strlen(format) + 2001], *ptr; strcpy (buf, format); ptr = (char*)buf; format = (const char*) buf; for( ;; ) { ptr = strchr( ptr, '%' ); if( ptr == NULL ) break; if( ptr[1] == 'm' ) { char errbuf[2001]; size_t errlen; #ifndef WIN32 strerror_r( errno, errbuf, 1001 ); #else int sockerr = WSAGetLastError( ); if( sockerr ) { strncpy( errbuf, net_strerror( sockerr ), 1001 ); WSASetLastError( sockerr ); } if ((sockerr == 0) || (strcmp ("Unknown network stack error", errbuf) == 0)) strncpy( errbuf, strerror( errno ), 1001 ); #endif errbuf[1000] = 0; /* Escape '%' from the error string */ for( char *percent = strchr( errbuf, '%' ); percent != NULL; percent = strchr( percent + 2, '%' ) ) { memmove( percent + 1, percent, strlen( percent ) + 1 ); } errlen = strlen( errbuf ); memmove( ptr + errlen, ptr + 2, strlen( ptr + 2 ) + 1 ); memcpy( ptr, errbuf, errlen ); break; /* Only once, so we don't overflow */ } /* Looks for conversion specifier... */ do ptr++; while( *ptr && ( strchr( "diouxXeEfFgGaAcspn%", *ptr ) == NULL ) ); if( *ptr ) ptr++; /* ...and skip it */ } #endif /* Fill message information fields */ msg_item_t msg; msg.i_object_id = (uintptr_t)obj; msg.psz_object_type = (obj != NULL) ? obj->psz_object_type : "generic"; msg.psz_module = module; msg.psz_header = NULL; for (vlc_object_t *o = obj; o != NULL; o = o->p_parent) if (o->psz_header != NULL) { msg.psz_header = o->psz_header; break; } /* Pass message to subscribers */ // libvlc_priv_t *priv = libvlc_priv (obj->p_libvlc); va_list ap; va_copy (ap, args); // if (priv->b_color) // PrintColorMsg (&priv->i_verbose, type, &msg, format, ap); // else PrintDebug (type, &msg, format, ap); va_end (ap); vlc_rwlock_rdlock (&msg_lock); for (msg_subscription_t *sub = msg_head; sub != NULL; sub = sub->next) { va_copy (ap, args); sub->func (sub->opaque, type, &msg, format, ap); va_end (ap); } vlc_rwlock_unlock (&msg_lock); uselocale (locale); freelocale (c); } static void PrintDebug (int type, const msg_item_t *p_item, const char *format, va_list ap) { // const signed char *pverbose = d; FILE *stream = stderr; // if (*pverbose < 0 || *pverbose < (type - VLC_MSG_ERR)) // return; int canc = vlc_savecancel (); flockfile (stream); fprintf (stream, "[%p] ", (void *)p_item->i_object_id); if (p_item->psz_header != NULL) utf8_fprintf (stream, "[%s] ", p_item->psz_header); utf8_fprintf (stream, "%s %s%s: ", p_item->psz_module, p_item->psz_object_type, msg_type[type]); utf8_vfprintf (stream, format, ap); putc_unlocked ('\n', stream); #if defined (WIN32) || defined (__OS2__) fflush (stream); #endif funlockfile (stream); vlc_restorecancel (canc); }
vlc_object_t *debug = NULL; msg_Output(debug,"--------bank.c-----module_InitBank()---------------");