1 /*
   2     libparted - a library for manipulating disk partitions
   3     Copyright (C) 2000, 2005, 2007 Free Software Foundation, Inc.
   4 
   5     This program is free software; you can redistribute it and/or modify
   6     it under the terms of the GNU General Public License as published by
   7     the Free Software Foundation; either version 3 of the License, or
   8     (at your option) any later version.
   9 
  10     This program is distributed in the hope that it will be useful,
  11     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13     GNU General Public License for more details.
  14 
  15     You should have received a copy of the GNU General Public License
  16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17 */
  18 
  19 #include <config.h>
  20 #include <parted/parted.h>
  21 #include <parted/debug.h>
  22 
  23 #if ENABLE_NLS
  24 #  include <libintl.h>
  25 #  define _(String) dgettext (PACKAGE, String)
  26 #else
  27 #  define _(String) (String)
  28 #endif /* ENABLE_NLS */
  29 
  30 #ifdef DEBUG
  31 
  32 #if HAVE_BACKTRACE
  33 #include <execinfo.h>
  34 #endif
  35 
  36 static void default_handler ( const int level, const char* file, int line,
  37                 const char* function, const char* msg );
  38 static PedDebugHandler* debug_handler = &default_handler;
  39 
  40 
  41 /**
  42  * Default debug handler.
  43  * Will print all information to stderr.
  44  */
  45 static void default_handler ( const int level, const char* file, int line,
  46                 const char* function, const char* msg )
  47 {
  48         fprintf ( stderr, "[%d] %s:%d (%s): %s\n",
  49                         level, file, line, function, msg );
  50 }
  51 
  52 /**
  53  * Send a debug message.
  54  * Do not call this directly -- use PED_DEBUG() instead.
  55  *
  56  * level        log level, 0 ~= "print definitely"
  57  */
  58 void ped_debug ( const int level, const char* file, int line,
  59                  const char* function, const char* msg, ... )
  60 {
  61         va_list         arg_list;
  62         char*           msg_concat = ped_malloc(8192);
  63         
  64         va_start ( arg_list, msg );
  65                 vsnprintf ( msg_concat, 8192, msg, arg_list );
  66         va_end ( arg_list );
  67         
  68         debug_handler ( level, file, line, function, msg_concat );
  69 
  70         ped_free ( msg_concat );
  71 }
  72 
  73 /*
  74  * handler      debug handler; NULL for default handler
  75  */
  76 void ped_debug_set_handler ( PedDebugHandler* handler )
  77 {
  78         debug_handler = ( handler ? handler : default_handler );
  79 }
  80 
  81 /*
  82  * Check an assertion.
  83  * Do not call this directly -- use PED_ASSERT() instead.
  84  */
  85 int ped_assert ( int cond, const char* cond_text,
  86             const char* file, int line, const char* function )
  87 {
  88         PedExceptionOption      opt;
  89 
  90         if ( cond )
  91                 return 1;
  92 
  93 #if HAVE_BACKTRACE
  94         /* Print backtrace stack */
  95         void *stack[20];
  96         char **strings, **string;
  97         int size = backtrace(stack, 20);
  98         strings = backtrace_symbols(stack, size);
  99 
 100         if (strings) {
 101                 printf(_("Backtrace has %d calls on stack:\n"), size);
 102                 for (string = strings; size > 0; size--, string++)
 103                         printf("  %d: %s\n", size, *string);
 104 
 105                 free(strings);
 106         }
 107 #endif
 108 
 109         /* Throw the exception */
 110         opt = ped_exception_throw (
 111                 PED_EXCEPTION_BUG,
 112                 PED_EXCEPTION_IGNORE_CANCEL,
 113                 _("Assertion (%s) at %s:%d in function %s() failed."),
 114                 cond_text, file, line, function );
 115 
 116         return ( opt == PED_EXCEPTION_IGNORE );
 117 }
 118 
 119 #endif /* DEBUG */
 120