Newsgroup: it.comp.os.linux.software
Titolo: Re: Analizzatore Threads

 Marco
La cosa più semplice, portabile e scalabile? uno o più file di log
verbosi, e tanta pazienza.
È anche indipendente dal linguaggio in cui sviluppi.
Unico neo, devi farci l'occhio e abituarti ad utilizzarli. Una volta che
impari a leggerli in tempo (quasi) reale o in differita (dipende dai
tempi di esecuzione), guardando un file di log sarai in grado di sapere
vita morte e miracoli del tuo programma quando è stato mandato in
esecuzione.
PSK

 verbosi, e tanta pazienza.
parole sante.  molto meglio printf di un debugger (secondo me, YMMV).
Mi permetto di dare un contributo personale...
-----------------------Begin file: generr.hh-----------------------
//     Author: Maurizio Loreti, aka MLO or (HAM) I3NOO
//     Work:   University of Padova - Department of Physics
//             Via F. Marzolo, 8 - 35131 PADOVA - Italy
//     Phone:  
+39 (049) 827-7216
   FAX: 
+39 (049) 827-7102
//     EMail:  
lor...@pd.infn.it
//     WWW:    
http://www.pd.infn.it/~loreti/mlo.html
//
// -------------------------------------------------------------------
// General error printout routines
// -------------------------------------------------------------------
// $Id: generr.hh,v 1.4 2005/06/07 06:03:33 loreti Exp $
// -------------------------------------------------------------------
#ifndef GENERR_HH_
#define GENERR_HH_
#include <iostream>
#include <stdexcept>
#include <string>
namespace generr {
  template <typename T> void valnam(
    const char *   name,
    const T &      value,
    std::ostream & o      = std::cerr
  ) {
    // Prints on the output stream "o" the name of a variable and its
    // value.  The variable must have a valid "operator <<" defined.
    o << "  -> " << name << " = " << value << std::endl;
  }
  // Declares a procedure for the printout of generic error.  The
  // arguments are: file name; line number; severity level; error
  // message; and the output stream.
  void errmes(const char *, unsigned int, const char *,
              const char *, std::ostream & = std::cerr);
}
// Preprocessor macros to ease the use of the above procedures.
#define VALNAM(x)  generr::valnam(#x, x)
#define ERRMES(m)  generr::errmes(__FILE__, __LINE__, "Error",      m)
#define WARNMES(m) generr::errmes(__FILE__, __LINE__, "Warning",    m)
#define INFOMES(m) generr::errmes(__FILE__, __LINE__, "Info",       m)
#define DBGMES(m)  generr::errmes(__FILE__, __LINE__, "Debug info", m)
// A class derived from std::exception, that saves for the catcher
// informations about date, time, file name and line that may be
// retrieved and, if needed, printed.
class genex : public std::runtime_error {
private:
  char         _date[12];
  char         _time[9];
  std::string  _file;
  unsigned int _line;
  void datim();
public:
  genex(const char * w, const char * f, unsigned int l)
    : std::runtime_error(w), _file(f), _line(l) { datim(); }
  ~genex() throw() {}
  const char *        getDate() const { return _date; }
  const char *        getTime() const { return _time; }
  const std::string & getFile() const { return _file; }
  const unsigned int  getLine() const { return _line; }
};
// Preprocessor macros to ease the use of the above class
#define GENEX(w) throw genex(w, __FILE__, __LINE__)
#endif // GENERR_HH_
------------------------End file: generr.hh------------------------
-----------------------Begin file: generr.cxx----------------------
//     Author: Maurizio Loreti, aka MLO or (HAM) I3NOO
//     Work:   University of Padova - Department of Physics
//             Via F. Marzolo, 8 - 35131 PADOVA - Italy
//     Phone:  
+39 (049) 827-7216
   FAX: 
+39 (049) 827-7102
//     EMail:  
lor...@pd.infn.it
//     WWW:    
http://www.pd.infn.it/~loreti/mlo.html
//
// -------------------------------------------------------------------
// Implementation of the procedure declared in "generr.hh".
// According to the preprocessor symbol "GENERR_DATETIME", the message
// contains:
// GENERR_DATETIME = 1 : current time
// GENERR_DATETIME = 2 : current date and time
// GENERR_DATETIME = none of the above values : nothing
// -------------------------------------------------------------------
// $Id: generr.cxx,v 1.4 2005/06/07 06:03:33 loreti Exp $
// -------------------------------------------------------------------
#include <ctime>
#include "generr.hh"
using namespace std;
namespace {
  const char t_fmt[] = "%H:%M:%S";
  const char d_fmt[] = "%d-%b-%Y";
  const char a_fmt[] = "%d-%b-%Y %H:%M:%S";
}
namespace generr {
  void errmes(
    const char * fileName,
    unsigned int lineNumber,
    const char * severity,
    const char * message,
    ostream &    o              // Defaults to cerr
  ) {
#if GENERR_DATETIME == 1 || GENERR_DATETIME == 2
    time_t      now = time(0);
    struct tm * ptm = localtime(&now);
#if GENERR_DATETIME == 1
    char fmtNow[] = "HH:MM:SS";
    strftime(fmtNow, sizeof(fmtNow), t_fmt, ptm);
#else  // == 2
    char fmtNow[] = "DD-MMM-YYYY HH:MM:SS";
    strftime(fmtNow, sizeof(fmtNow), a_fmt, ptm);
#endif
    o << "* " << fmtNow << ' ';
#endif
    o << "* " << severity << " from file " << fileName
      << " at line "  << lineNumber << "\n* Message: "
      << message << endl;
  }
}
void genex::datim() {
  time_t      now = time(0);
  struct tm * ptm = localtime(&now);
  strftime(_date, sizeof(_date), d_fmt, ptm);
  strftime(_time, sizeof(_time), t_fmt, ptm);
}
------------------------End file: generr.cxx-----------------------
-------------------Begin file: main.cxx (esempio)------------------
#include <fstream>
#include <string>
#include "generr.hh"
using namespace std;
class strange {
private:
  string name;
  int value;
public:
  strange(const char * n, int v) : name(n), value(v) {}
  ~strange() {}
  void out(ostream & o) const {
    o << '(' << name << ", " << value << ')'; }
};
ostream & operator << (
  ostream & o,
  const strange & s
) {
  s.out(o);
  return o;
}
void procedure() {
  GENEX("Self-destructing");
}
void line(
  const char * target
) {
  cerr << "------------------------------ "
       << target << " ------------------------------\n\n";
}
int main() {
  string fileName = "abc.dat";
  const char myName[] = "Maurizio Loreti";
  int i = 42;
  double pig = 3.14;
  strange ss("foo", 666);
  DBGMES("program started");
  line("Trying ERRMES");
  ifstream ifs(fileName.c_str());
  if (!ifs) {
    ERRMES("couldn't open file");
    VALNAM(fileName);
    VALNAM(myName);
    VALNAM(i);
    VALNAM(pig);
    VALNAM(ss);
  }
  cerr << '\n';
  line("Trying GENEX");
  try {
    procedure();
  } catch (const genex & g) {
    cerr << "\t*** Howdy!  I am the General Exception Catcher! "
         << "***\n\n\tI am afraid that, in the line " << g.getLine()
         << " of the file \"" << g.getFile()
         << "\",\n\tsome shit happened in the day of the Lord "
         << g.getDate() << ";\n\tand exactly at " << g.getTime()
         << " (local time, of course).\n\n\tThe message I got is:\t\t\""
         << g.what() << "\"\n\n";
  }
  DBGMES("program ended");
}
--------------------End file: main.cxx (esempio)-------------------
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Dept. of Physics, Univ. of Padova, Italy              ROT13: 
ybe...@cq.vasa.vg