2002-05-08 Marcus Brinkmann <marcus@g10code.de>

* debug.h: New file.
	* Makefile.am (libgpgme_la_SOURCES): Add debug.h.
	* util.h: Removed all prototypes and declarations related to
	debugging.  Include "debug.h".

	* debug.c (debug_level): Comment variable and remove superfluous
	zero initializer.
	(errfp): Likewise.
	(_gpgme_debug_enabled): Function removed.
	(struct debug_control_s): Definition removed.
	(_gpgme_debug_level): Function removed.
	(_gpgme_debug_begin): Rewritten to use vasprintf.  Accept a
	pritnf-style format specification and a variable number of
	arguments.
	(_gpgme_debug_add): Rewritten using vasprintf.  Expect that format
	starts out with "%s" for simplicity.
	(_gpgme_debug_end): Rewritten using vasprintf.  Do not accept a
	TEXT argument anymore.

	* posix-io.c (_gpgme_io_select): Use new level argument for
	DEBUG_BEGIN instead explicit if construct.

	* debug.c (debug_init): Remove superfluous zero initializer,
	remove volatile flag of INITIALIZED.  Do not use the
	double-checked locking algorithm, it is fundamentally flawed and
	will empty your fridge (on a more serious note, despite the
	volatile flag it doesn't give you the guarantee you would expect,
	for example on a DEC Alpha or an SMP machine.  The volatile only
	serializes accesses to the volatile variable, but not to the other
	variables).
This commit is contained in:
Marcus Brinkmann 2002-05-08 03:57:42 +00:00
parent 39a679ed75
commit 5d03d9b7eb
5 changed files with 165 additions and 216 deletions

View File

@ -1,3 +1,36 @@
2002-05-08 Marcus Brinkmann <marcus@g10code.de>
* debug.h: New file.
* Makefile.am (libgpgme_la_SOURCES): Add debug.h.
* util.h: Removed all prototypes and declarations related to
debugging. Include "debug.h".
* debug.c (debug_level): Comment variable and remove superfluous
zero initializer.
(errfp): Likewise.
(_gpgme_debug_enabled): Function removed.
(struct debug_control_s): Definition removed.
(_gpgme_debug_level): Function removed.
(_gpgme_debug_begin): Rewritten to use vasprintf. Accept a
pritnf-style format specification and a variable number of
arguments.
(_gpgme_debug_add): Rewritten using vasprintf. Expect that format
starts out with "%s" for simplicity.
(_gpgme_debug_end): Rewritten using vasprintf. Do not accept a
TEXT argument anymore.
* posix-io.c (_gpgme_io_select): Use new level argument for
DEBUG_BEGIN instead explicit if construct.
* debug.c (debug_init): Remove superfluous zero initializer,
remove volatile flag of INITIALIZED. Do not use the
double-checked locking algorithm, it is fundamentally flawed and
will empty your fridge (on a more serious note, despite the
volatile flag it doesn't give you the guarantee you would expect,
for example on a DEC Alpha or an SMP machine. The volatile only
serializes accesses to the volatile variable, but not to the other
variables).
2002-05-03 Werner Koch <wk@gnupg.org> 2002-05-03 Werner Koch <wk@gnupg.org>
* engine-gpgsm.c (_gpgme_gpgsm_new): Redirect any gpgsm error * engine-gpgsm.c (_gpgme_gpgsm_new): Redirect any gpgsm error

View File

@ -68,7 +68,8 @@ libgpgme_la_SOURCES = \
sema.h io.h \ sema.h io.h \
${system_components} \ ${system_components} \
mutex.h \ mutex.h \
gpgme.c debug.c version.c errors.c debug.c debug.h \
gpgme.c version.c errors.c
errors.c : gpgme.h errors.c : gpgme.h
$(srcdir)/mkerrors < $(srcdir)/gpgme.h > errors.c $(srcdir)/mkerrors < $(srcdir)/gpgme.h > errors.c

View File

@ -1,5 +1,5 @@
/* debug.c /* debug.c - helpful output in desperate situations
* Copyright (C) 2001 g10 Code GmbH * Copyright (C) 2001, 2002 g10 Code GmbH
* *
* This file is part of GPGME. * This file is part of GPGME.
* *
@ -35,206 +35,175 @@
#include "util.h" #include "util.h"
#include "sema.h" #include "sema.h"
/* Lock to serialize initialization of the debug output subsystem and
output of actual debug messages. */
DEFINE_STATIC_LOCK (debug_lock); DEFINE_STATIC_LOCK (debug_lock);
struct debug_control_s { /* The amount of detail requested by the user, per environment
FILE *fp; variable GPGME_DEBUG. */
char fname[100]; static int debug_level;
};
static int debug_level = 0; /* The output stream for the debug messages. */
static FILE *errfp = NULL; static FILE *errfp;
/****************
* remove leading and trailing white spaces /* Remove leading and trailing white spaces. */
*/
static char * static char *
trim_spaces( char *str ) trim_spaces (char *str)
{ {
char *string, *p, *mark; char *string, *p, *mark;
string = str; string = str;
/* find first non space character */ /* Find first non space character. */
for( p=string; *p && isspace( *(byte*)p ) ; p++ ) for (p = string; *p && isspace (*(byte *) p); p++)
; ;
/* move characters */ /* Move characters. */
for( (mark = NULL); (*string = *p); string++, p++ ) for (mark = NULL; (*string = *p); string++, p++)
if( isspace( *(byte*)p ) ) { if (isspace (*(byte *) p))
if( !mark ) {
mark = string ; if (!mark)
} mark = string;
else }
mark = NULL ; else
if( mark ) mark = NULL;
*mark = '\0' ; /* remove trailing spaces */ if (mark)
*mark = '\0'; /* Remove trailing spaces. */
return str ; return str;
} }
static void static void
debug_init (void) debug_init (void)
{ {
static volatile int initialized = 0; static int initialized;
if (initialized) LOCK (debug_lock);
return; if (!initialized)
LOCK (debug_lock); {
if (!initialized) { const char *e = getenv ("GPGME_DEBUG");
const char *e = getenv ("GPGME_DEBUG"); const char *s1, *s2;;
const char *s1, *s2;;
initialized = 1; initialized = 1;
debug_level = 0; errfp = stderr;
errfp = stderr; if (e)
if (e) { {
debug_level = atoi (e); debug_level = atoi (e);
s1 = strchr (e, ':'); s1 = strchr (e, ':');
if (s1 if (s1)
{
#ifndef HAVE_DOSISH_SYSTEM #ifndef HAVE_DOSISH_SYSTEM
&& getuid () == geteuid () if (getuid () == geteuid ())
{
#endif #endif
) { char *p;
char *p; FILE *fp;
FILE *fp;
s1++; s1++;
if ( !(s2 = strchr (s1, ':')) ) if (!(s2 = strchr (s1, ':')))
s2 = s1 + strlen(s1); s2 = s1 + strlen (s1);
p = xtrymalloc (s2-s1+1); p = xtrymalloc (s2 - s1 + 1);
if (p) { if (p)
memcpy (p, s1, s2-s1); {
p[s2-s1] = 0; memcpy (p, s1, s2 - s1);
trim_spaces (p); p[s2-s1] = 0;
fp = fopen (p,"a"); trim_spaces (p);
if (fp) { fp = fopen (p,"a");
setvbuf (fp, NULL, _IOLBF, 0); if (fp)
errfp = fp; {
} setvbuf (fp, NULL, _IOLBF, 0);
xfree (p); errfp = fp;
} }
} xfree (p);
}
#ifndef HAVE_DOSISH_SYSTEM
}
#endif
}
} }
if (debug_level > 0) if (debug_level > 0)
fprintf (errfp,"gpgme_debug: level=%d\n", debug_level); fprintf (errfp, "gpgme_debug: level=%d\n", debug_level);
} }
UNLOCK (debug_lock); UNLOCK (debug_lock);
}
int
_gpgme_debug_level ()
{
return debug_level;
} }
/* Log the formatted string FORMAT at debug level LEVEL or higher. */
void void
_gpgme_debug (int level, const char *format, ...) _gpgme_debug (int level, const char *format, ...)
{ {
va_list arg_ptr ; va_list arg_ptr;
debug_init (); debug_init ();
if ( debug_level < level ) if (debug_level < level)
return; return;
va_start ( arg_ptr, format ) ; va_start (arg_ptr, format);
LOCK (debug_lock); LOCK (debug_lock);
vfprintf (errfp, format, arg_ptr) ; vfprintf (errfp, format, arg_ptr);
va_end ( arg_ptr ) ; va_end (arg_ptr);
if( format && *format && format[strlen(format)-1] != '\n' ) if(format && *format && format[strlen (format) - 1] != '\n')
putc ('\n', errfp); putc ('\n', errfp);
UNLOCK (debug_lock); UNLOCK (debug_lock);
fflush (errfp); fflush (errfp);
} }
/* Start a new debug line in *LINE, logged at level LEVEL or higher,
and starting with the formatted string FORMAT. */
void void
_gpgme_debug_begin ( void **helper, int level, const char *text) _gpgme_debug_begin (void **line, int level, const char *format, ...)
{ {
struct debug_control_s *ctl; va_list arg_ptr;
debug_init (); debug_init ();
if (debug_level < level)
*helper = NULL;
if ( debug_level < level )
return;
ctl = xtrycalloc (1, sizeof *ctl );
if (!ctl) {
_gpgme_debug (255, __FILE__ ":" STR2(__LINE__)": out of core");
return;
}
/* Oh what a pitty that we don't have a asprintf or snprintf under
* Windoze. We definitely should write our own clib for W32! */
sprintf ( ctl->fname, "/tmp/gpgme_debug.%d.%p", getpid (), ctl );
#if defined (__GLIBC__) || defined (HAVE_DOSISH_SYSTEM)
ctl->fp = fopen (ctl->fname, "w+x");
#else
{ {
int fd = open (ctl->fname, O_WRONLY|O_TRUNC|O_CREAT|O_EXCL, /* Disable logging of this line. */
S_IRUSR|S_IWUSR ); *line = NULL;
if (fd == -1) return;
ctl->fp = NULL;
else
ctl->fp = fdopen (fd, "w+");
} }
#endif
if (!ctl->fp) {
_gpgme_debug (255,__FILE__ ":" STR2(__LINE__)": failed to create `%s'",
ctl->fname );
xfree (ctl);
return;
}
*helper = ctl;
_gpgme_debug_add (helper, "%s", text );
}
int va_start (arg_ptr, format);
_gpgme_debug_enabled (void **helper) vasprintf ((char **) line, format, arg_ptr);
{ va_end (arg_ptr);
return helper && *helper;
} }
/* Add the formatted string FORMAT to the debug line *LINE. */
void void
_gpgme_debug_add (void **helper, const char *format, ...) _gpgme_debug_add (void **line, const char *format, ...)
{ {
struct debug_control_s *ctl = *helper; va_list arg_ptr;
va_list arg_ptr ; char *toadd;
char *result;
if ( !*helper ) if (!line)
return; return;
va_start ( arg_ptr, format ) ; va_start (arg_ptr, format);
vfprintf (ctl->fp, format, arg_ptr) ; vasprintf (&toadd, format, arg_ptr);
va_end ( arg_ptr ) ; va_end (arg_ptr);
asprintf (&result, "%s%s", *(char **) line, toadd);
free (*line);
free (toadd);
*line = result;
} }
/* Finish construction of *LINE and send it to the debug output
stream. */
void void
_gpgme_debug_end (void **helper, const char *text) _gpgme_debug_end (void **line)
{ {
struct debug_control_s *ctl = *helper; if (!line)
int c, last_c=EOF; return;
if ( !*helper ) /* The smallest possible level is 1, so force logging here by
return; using that. */
_gpgme_debug (1, "%s", *line);
_gpgme_debug_add (helper, "%s", text ); free (*line);
fflush (ctl->fp); /* we need this for the buggy Windoze libc */ *line = NULL;
rewind (ctl->fp);
LOCK (debug_lock);
while ( (c=getc (ctl->fp)) != EOF ) {
putc (c, errfp);
last_c = c;
}
if (last_c != '\n')
putc ('\n', errfp);
UNLOCK (debug_lock);
fclose (ctl->fp);
remove (ctl->fname);
xfree (ctl);
*helper = NULL;
} }

View File

@ -295,15 +295,14 @@ _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds)
FD_ZERO (&writefds); FD_ZERO (&writefds);
max_fd = 0; max_fd = 0;
if (_gpgme_debug_level () > 2) DEBUG_BEGIN (dbg_help, 3, "gpgme:select on [ ");
DEBUG_BEGIN (dbg_help, "gpgme:select on [ ");
any = 0; any = 0;
for (i = 0; i < nfds; i++) for (i = 0; i < nfds; i++)
{ {
if (fds[i].fd == -1) if (fds[i].fd == -1)
continue; continue;
if (fds[i].frozen) if (fds[i].frozen)
DEBUG_ADD1 (dbg_help, "f%d ", fds[i].fd ); DEBUG_ADD1 (dbg_help, "f%d ", fds[i].fd);
else if (fds[i].for_read) else if (fds[i].for_read)
{ {
assert (!FD_ISSET (fds[i].fd, &readfds)); assert (!FD_ISSET (fds[i].fd, &readfds));
@ -339,9 +338,8 @@ _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds)
return -1; /* error */ return -1; /* error */
} }
if (_gpgme_debug_level () > 2) DEBUG_BEGIN (dbg_help, 3, "select OK [ ");
DEBUG_BEGIN (dbg_help, "select OK [ "); if (DEBUG_ENABLED (dbg_help))
if (DEBUG_ENABLED(dbg_help))
{ {
for (i = 0; i <= max_fd; i++) for (i = 0; i <= max_fd; i++)
{ {

View File

@ -23,6 +23,7 @@
#define UTIL_H #define UTIL_H
#include "types.h" #include "types.h"
#include "debug.h"
void *_gpgme_malloc (size_t n ); void *_gpgme_malloc (size_t n );
void *_gpgme_calloc (size_t n, size_t m ); void *_gpgme_calloc (size_t n, size_t m );
@ -41,59 +42,6 @@ void _gpgme_free ( void *a );
#define DIM(v) (sizeof(v)/sizeof((v)[0])) #define DIM(v) (sizeof(v)/sizeof((v)[0]))
#define DIMof(type,member) DIM(((type *)0)->member) #define DIMof(type,member) DIM(((type *)0)->member)
#ifndef STR
#define STR(v) #v
#endif
#define STR2(v) STR(v)
void _gpgme_debug (int level, const char *format, ...);
int _gpgme_debug_level (void);
void _gpgme_debug_begin ( void **helper, int level, const char *text);
int _gpgme_debug_enabled ( void **helper );
void _gpgme_debug_add (void **helper, const char *format, ...);
void _gpgme_debug_end (void **helper, const char *text);
#define DEBUG0(x) _gpgme_debug (1, __FILE__ ":" \
STR2 (__LINE__) ": " x )
#define DEBUG1(x,a) _gpgme_debug (1, __FILE__ ":" \
STR2 (__LINE__)": " x, (a) )
#define DEBUG2(x,a,b) _gpgme_debug (1, __FILE__ ":" \
STR2 (__LINE__) ": " x, (a), (b) )
#define DEBUG3(x,a,b,c) _gpgme_debug (1, __FILE__ ":" \
STR2 (__LINE__) ": " x, (a), (b), (c) )
#define DEBUG4(x,a,b,c,d) _gpgme_debug (1, __FILE__ ":" \
STR2 (__LINE__) ": " x, (a), (b), (c), (d) )
#define DEBUG5(x,a,b,c,d,e) _gpgme_debug (1, __FILE__ ":" \
STR2 (__LINE__) ": " x, (a), (b), (c), (d), (e) )
#define DEBUG6(x,a,b,c,d,e,f) _gpgme_debug (1, __FILE__ ":" \
STR2 (__LINE__) ": " x, (a), (b), (c), (d), (e), (f) )
#define DEBUG7(x,a,b,c,d,e,f,g) _gpgme_debug (1, __FILE__ ":" \
STR2 (__LINE__) ": " x, (a), (b), (c), (d), (e), (f), (g) )
#define DEBUG8(x,a,b,c,d,e,f,g,h) _gpgme_debug (1, __FILE__ ":" \
STR2 (__LINE__) ": " x, (a), (b), (c), (d), (e), (f), (g), (h) )
#define DEBUG9(x,a,b,c,d,e,f,g,h,i) _gpgme_debug (1, __FILE__ ":" \
STR2 (__LINE__) ": " x, (a), (b), (c), (d), (e), (f), (g), (h), (i) )
#define DEBUG10(x,a,b,c,d,e,f,g,h,i,j) _gpgme_debug (1, __FILE__ ":" \
STR2 (__LINE__) ": " x, (a), (b), (c), (d), (e), (f), (g), (h), (i), (j) )
#define DEBUG_BEGIN(y,x) _gpgme_debug_begin (&(y), 1, __FILE__ ":" \
STR2 (__LINE__) ": " x )
#define DEBUG_ENABLED(y) _gpgme_debug_enabled(&(y))
#define DEBUG_ADD0(y,x) _gpgme_debug_add (&(y), (x), \
)
#define DEBUG_ADD1(y,x,a) _gpgme_debug_add (&(y), (x), \
(a) )
#define DEBUG_ADD2(y,x,a,b) _gpgme_debug_add (&(y), (x), \
(a), (b) )
#define DEBUG_ADD3(y,x,a,b,c) _gpgme_debug_add (&(y), (x), \
(a), (b), (c) )
#define DEBUG_ADD4(y,x,a,b,c,d) _gpgme_debug_add (&(y), (x), \
(a), (b), (c), (d) )
#define DEBUG_ADD5(y,x,a,b,c,d,e) _gpgme_debug_add (&(y), (x), \
(a), (b), (c), (d), (e) )
#define DEBUG_END(y,x) _gpgme_debug_end (&(y), (x) )
#ifndef HAVE_STPCPY #ifndef HAVE_STPCPY