Signed-off-by: Nikola Pajkovsky <npajkovs(a)redhat.com>
---
doc/CodingStyle | 64 -------------------
doc/DESIGN | 147 ------------------------------------------
doc/HOW_TO_TEST | 41 ------------
doc/IMPLEMENTATION | 89 --------------------------
doc/INTERPRETED_LANGUAGES | 113 ---------------------------------
doc/PLUGINS-HOWTO | 155 ---------------------------------------------
doc/coding-style | 64 +++++++++++++++++++
doc/design | 147 ++++++++++++++++++++++++++++++++++++++++++
doc/how-to-test | 41 ++++++++++++
doc/implementation | 89 ++++++++++++++++++++++++++
doc/interpreted-languages | 113 +++++++++++++++++++++++++++++++++
doc/plugins-howto | 155 +++++++++++++++++++++++++++++++++++++++++++++
12 files changed, 609 insertions(+), 609 deletions(-)
delete mode 100644 doc/CodingStyle
delete mode 100644 doc/DESIGN
delete mode 100644 doc/HOW_TO_TEST
delete mode 100644 doc/IMPLEMENTATION
delete mode 100644 doc/INTERPRETED_LANGUAGES
delete mode 100644 doc/PLUGINS-HOWTO
create mode 100644 doc/coding-style
create mode 100644 doc/design
create mode 100644 doc/how-to-test
create mode 100644 doc/implementation
create mode 100644 doc/interpreted-languages
create mode 100644 doc/plugins-howto
diff --git a/doc/CodingStyle b/doc/CodingStyle
deleted file mode 100644
index 3a254b7..0000000
--- a/doc/CodingStyle
+++ /dev/null
@@ -1,64 +0,0 @@
-Coding style used in abrt
-=================================
-
-1. Class
---------
-1.1 Class has to start with 'C'
-
-1.2 Method
------------
-1.2.1 method starts witch a capital letter
-1.2.2 method name can contain only letters
-1.2.3 parameter of a method has to start with the letter 'p'
-
-1.3 Attribute
--------------
-1.3.1 non-float attribute has to start with "m_n"
-1.3.2 float attribute has to start with "m_f"
-1.3.3 double attribute has to start with "m_d"
-1.3.4 bool attribute has to start with "m_b"
-1.3.5 string/char attribute has to start with "m_s"
-1.3.6 pointer attribute has to start with "m_p"
-1.3.7 template attribute has to start with a template name "m_map"
-1.3.8 otherwise "m_"
-
-2. Type
--------
-2.1 every type has to end with "_t"
-2.2 types created from templates has to start with a template name
-2.3 words in a type has to be separated with "_"
-
-3. Statement
-------------
-3.1 "if", "while" and "for" has to have {} every time.
-3.2 { is on the new line every time
-
-4. Example
-----------
-
-typedef std::map<int, int> map_new_type_t;
-
-class CAwesomeClass
-{
- private:
- map_new_type_t m_NewType;
- std::string m_sName;
- COtherClass* m_pOtherClass;
- void PrivateFunction(int pParameter);
- public:
- CAwesomeClass(std::string pName) :
- m_sName(pName), m_pOtherClass(NULL)
- {}
-};
-
-void CAwesomeClass::PrivateFunction(int pParameter)
-{
- if (pParameter != "")
- {
- // do something
- }
- else
- {
- // do something else
- }
-}
diff --git a/doc/DESIGN b/doc/DESIGN
deleted file mode 100644
index 6074457..0000000
--- a/doc/DESIGN
+++ /dev/null
@@ -1,147 +0,0 @@
- Design goals
-
-We want to catch kernel oopses, binary program crashes (coredumps)
-and interpreted languages crashes (Python exceptions, maybe more
-in the future).
-
-We want to support the following use cases:
-
-* Home/office user with minimal administration
-
-In this scenario, user expects that abrt will work "out of the box"
-with minimal configuration. It will be sufficient if crashes
-just show a GUI notification, and user can invoke a GUI tool
-to process the crash and report it to bugzilla etc.
-
-The configuration (like bugzilla address, username, password)
-needs to be done via GUI dialogs from the same GUI tool.
-
-* Standalone server
-
-The server is installed by an admin. It may lack GUI.
-Admin is willing to do somewhat more complex configuration.
-Crashes should be recorded, and either processed at once
-or reported to the admin by email etc. Admin may log in
-and manually request crash(es) to be processed and reported,
-using GUI or CLI tools.
-
-* Mission critical servers, server farms etc.
-
-Admins are expected to be competent and willing to set up complex
-configurations. They might want to avoid any complex crash processing
-on the servers - for example, it does not make much sense and/or
-can be considered insecure to download debuginfo packages
-to such servers. Admins may want to send "raw" crash dumps
-to a dedicated server(s) for processing (backtrace, etc).
-
-
- Design
-
-Abrt design should be flexible enough to accomodate all
-of the above usage scenarios.
-
-The description below is not what abrt does now.
-It is (currently incomplete) design notes on how we want
-it to achieve design goals.
-
-Since currently we do not know how to dump oops on demand,
-we can only poll for it. There is a small daemon which polls
-kernel message buffer and dumps oopses when it sees them.
-The dump is written into /var/spool/abrt/DIR.
-After this, daemon spawns "abrt-process -d /var/spool/abrt/DIR"
-which processes it according to configuration in /etc/abrt/*.conf.
-
-In order to catch binary crashes, we install a handler for it
-in /proc/sys/kernel/core_pattern (by setting it to
-"|/usr/libexec/abrt-hook-ccpp /var/spool/abrt %p %s %u").
-When process dumps core, the dump is written into /var/spool/abrt/DIR.
-After this, abrt-hook-ccpp spawns "abrt-process -d /var/spool/abrt/DIR"
-and terminates.
-
-When python program crashes, it invokes internel python subroutine
-which dumps crash info into ~/abrt/spool/DIR.
-[this is a tentative plan, currently we dump in /var/spool/abrt/DIR]
-After this, it spawns "abrt-process -d ~/abrt/spool/DIR"
-and terminates.
-
-[Problem: dumping to /var/spool/abrt/DIR needs world-writable
-/var/spool/abrt and allows user to go way over his
-disk quota. Dumping to ~/abrt/spool/DIR makes it difficult
-to present a list of all crashes which happened on the machine -
-for example, root-owned processes cannot even access user data
-in ~user/* if /home is on NFS4...
-]
-
-When user (admin) wants to see the list of dumped crashes and
-process them, he runs abrt-gui or abrt-cli. These programs
-perform a dbus call to "com.redhat.abrt" on a system dbus.
-If there is no program with this name on it, dbus autostart
-will invoke "abrt-process", which registers "com.redhat.abrt"
-and processes the call(s).
-
-abrt-process will terminate after a timeout (a few minutes)
-if no new dbus calls are arriving to it.
-
-The key dbus calls served by abrt-process are:
-
-- GetCrashInfos(): returns a vector_map_crash_data_t (vector_map_vector_string_t)
- of crashes for given uid
-
v[N]["executable"/"uid"/"kernel"/"backtrace"][N] =
"contents"
-[see above the problem with producing this list]
-- CreateReport(UUID): starts creating a report for /var/spool/abrt/DIR with this UUID.
- Returns job id (uint64).
- After it returns, when report creation thread has finished,
- JobDone(client_dbus_ID,UUID) dbus signal is emitted.
- [Problem: how to do privilegged plugin specific actions?]
- Solution: if plugin needs an access to some root only accessible dir then
- abrt should be run by root anyway
- - debuginfo gets installed using pk-debuginfo-install, which cares about
- privileges itself, so no problem here
-- GetJobResult(UUID): returns map_crash_data_t (map_vector_string_t)
-- Report(map_crash_data_t (map_vector_string_t)):
- "Please report this crash": calls Report() of all registered reporter
plugins
- Returns report_status_t (map_vector_string_t) - the status of each call
-- DeleteDebugDump(UUID): delete corresponding /var/spool/abrt/DIR. Returns bool
-
-
- Development plan
-
-Since current code does not match the planned design, we need to gradually
-change the code to "morph" it into the desired shape.
-
-Done:
-
-* Make abrtd dbus startable.
-* Add -t TIMEOUT_SEC option to abrtd. {done}
-* Make abrt-gui start abrtd on demand, so that abrt-gui can be started
- even if abrtd does not run at the moment. (doesn't work in some cases!)
-
-Planned steps:
-
-* make kerneloops plugin into separate daemon (convert it to a hook
- and get rid of "cron plugins" which are wrong idea since the begining)
- - and make it to the service (write an initscript)
-* make C/C++ hook to be started by init script
- - init scritp would run ccpp-hook --init whic shoudl just set the core_pattern, which
is now done by the C analyzer plugin
-* hooks will start the daemon on-demand using dbus
- - this is something I'm not sure if it's good idea, but dbus is becoming
- to be "un-installable" on Fedora, it's probably ok
-* simplify abrt.conf:
- - move all plugin related info to plugins/<plugin>.conf
- - enabled, action association, etc ...
- - make abrtd to parse plugins/*.conf and set the config options
- that it understand
- - this will fix the case when this is in abrt.conf
-
- [Cron]
- KerneloopsScanner = 120
-
- because this should be in plugins/kerneloops.conf
- and thus shouldn't exist if kerneloops-addon is
- not installed
-* ???
-* ???
-* ???
-* ???
-* ???
-* Take over the world
diff --git a/doc/HOW_TO_TEST b/doc/HOW_TO_TEST
deleted file mode 100644
index 425a2b3..0000000
--- a/doc/HOW_TO_TEST
+++ /dev/null
@@ -1,41 +0,0 @@
-How to test before releasing new update:
-
-I. Build and install
-===================
-a) build the packages as scratch in koji
-b) download and install (the best is to create a local repo and try to install it using
yum)
-c) create a repository and try to update from previous packages
-d) start the daemon and check logs for any sign of a problem
-e) try to update from previous Fedora version using created repository
-
-II. Crash detection
-=====================
- == 1. Default crash detection ==
- a) kill some C/C++ app with kill -9 and watch if it's detected by abrt
- b) edit some packaged python script to raise an exception and watch is abrt
- detects it
- c) use our saved kerneloopses and test detection of oopses
-
- == 2. Advanced crash detection ==
- a) crash some app that comes from unsigned package - abrt should ignore it
- b) disable the gpg check and try repeat step a) - abrt shouldn't ignore it
-
-- try to add some crash-time action and test if it works
-
-III. Reporting
-=============
- == 1. Reporting to bugzilla ==
- a) try to report some crash to bz using gui
- - gui should ask for login+pass
- - crash should be reported after filling the right credentials
- b) try to report using gui without gnome-keyring
- - gui should ask for login+pass
- - crash should be reported after filling the right credentials
- - login+pass won't be saved
- c) try to report every supported crash abrt detects C/C++, oops, python script
- d) try to report some crash with bad backtrace - this should fail
- e) repeat this with cli
-
-- test reporting with all reporters plugins like: ticketuploader, filetransport, etc..
- repeating the step 'a' to 'e'
-
diff --git a/doc/IMPLEMENTATION b/doc/IMPLEMENTATION
deleted file mode 100644
index 72f12c7..0000000
--- a/doc/IMPLEMENTATION
+++ /dev/null
@@ -1,89 +0,0 @@
-Implementation:
-
-C/C++ handling:
-==============
-
-we change /proc/sys/kernel/core_pattern to invoke abrtd helper to save
-the coredump of crashing app:
-* helper source code:
http://git.fedorahosted.org/git/abrt.git?p=abrt.git;a=blob_plain;f=src/Ho...
-the code responsible for this:
-
- #define CORE_PATTERN "|/usr/libexec/abrt-hook-ccpp"
"/var/spool/abrt" %p %s %u"
- ofstream fOutCorePattern;
- fOutCorePattern.open(CORE_PATTERN_IFACE);
- if (fOutCorePattern.is_open())
- {
- fOutCorePattern << CORE_PATTERN << endl;
- fOutCorePattern.close();
- }
-
-%p - pid
-%s - signal
-%u - uid
-
-when some crash occurs abrt-hook-ccpp is invoked to store the coredump and some other
info
-read from /proc/<pid>/:
-
-executable:
- char buf[sizeof("/proc/%u/exe") + sizeof(int)*3];
- sprintf(buf, "/proc/%u/exe", (int)pid);
- readlink(buf);
-
-cmdline:
- char path[sizeof("/proc/%u/cmdline") + sizeof(int)*3];
- sprintf(path, "/proc/%u/cmdline", (int)pid);
-
-both is saved to file in /var/spool/abrt/ccpp-<time>-<pid> readable
-only by owner the crashed process:
- int fd = open(pPath, O_WRONLY | O_TRUNC | O_CREAT, 0666);
- if(fd){
- do {
- n = write(fd, buf, count);
- } while (n < 0 && errno == EINTR);
- }
-
-when the hook is done it signalize the daemon (be removing the lock file) and
-daemon process the written info and saves some aditional information:
- analyzer : name of the plugin used to analyze the crash (ccpp, python)
- component : source package name
- description : package description (will be removed soon)
- kernel : kernel version
- release : Fedora release string
- uid : uid of the owner of the crashed app
- architecture : architecture (i386, x86_64,etc)
- package : package name
- reason : e.g "Process was terminated by signal 11 (Segmentation
fault)"
- time : unix time of the crash
-
-2. send dbus signal (broadcast) about new crash, this signal contains two informations:
- 1. uid of the app owner
- 2. package name
-
-This is all what happens when some app crashes, the next step is to process
-the coredump and extract the backtrace. This is done on user demand by calling
-getReport(UUID) method or automatically if admin sets it in /etc/abrt/abrt.conf
-* UUID is unique id of the crash in the database, every user is allowed to see only
- his own crashes or kerneloops crashes
-- see
http://git.fedorahosted.org/git/abrt.git?p=abrt.git;a=blob;f=lib/Plugins/... line
394
- for more details
-
-1. processing coredump:
- a) determine if the crashed binary belongs to some installed package
- if it does then:
- b) daemon tries to install the debuginfo issuing this command:
-
-execlp("abrt-debuginfo-install", "abrt-debuginfo-install", coredump,
tempdir, debuginfo_dirs, NULL);
-
-abrt-debuginfo-install is a shell script using elfutils to get build-ids from coredump
and the use
-"yum provides" and "yumdownloader" to determine and download the
missing debuginfo packages
-* script source code:
http://git.fedorahosted.org/git/abrt.git?p=abrt.git;a=blob_plain;f=src/Da...
- c) run gdb and get backtrace from coredump:
- see
http://git.fedorahosted.org/git/abrt.git?p=abrt.git;a=blob_plain;f=lib/Pl...
line 260
- - gdb is run with the same privileges as the crashed app (setregid, setreuid)
- d) BT is saved to same directory where the coredump is
-
-Once the backtrace is processed all data from the
/var/spool/abrt/ccpp-<time>-<pid> is sent
-over dbus to the client and then user can edit the backtrace. When user is happy about
-the report and command the client (gui, tui) to send the it, the client sends the data
back
-to the daemon calling the Report(data) method over the dbus. The actual reporting is done
by
-the respective plugin which is loaded in daemon.
diff --git a/doc/INTERPRETED_LANGUAGES b/doc/INTERPRETED_LANGUAGES
deleted file mode 100644
index e79a132..0000000
--- a/doc/INTERPRETED_LANGUAGES
+++ /dev/null
@@ -1,113 +0,0 @@
-This document describes the interaction between ABRT and interpreted
-languages.
-
-Interpreted language is a programming language where the programs
-written in that language are not translated into the machine code of
-the computer it is on, but interpreted by another software program
-known as an interpreter.
-
-In order to handle interpreted language correctly, ABRT needs a hook
-in the language's interpreter. The hook catches serious application
-misbehaviors (such as uncaught exceptions, invalid bytecode, missing
-library) inside the interpreter and reports the misbehaviors to
-ABRT. Hook is usually responsible for assembling the backtrace.
-
-Another issue are the crashes of the interpreter, which are catched by
-the CCpp plugin. When the support for specific interpreter is missing
-all these crashes are reported to the interpreter component when
-submitting the crash using Bugzilla plugin, regardless of application
-executed by the interpreter. To change this, the interpreter should be
-handled in src/Daemon/MiddleWare.cpp (see how it is done for Python).
-
-ABRT currently support only CPython interpreter (the mainstream Python
-implementation). Perl, Java, Ruby, and Mono interpreter hooks are yet
-to be written. It might be necessary to modify ABRT to support a new
-interpreter (patches welcomed).
-
-Communication between ABRT and hooks
-====================================
-
-Hook might be a binary plugin plugged to the interpreter, or it might
-be interpreted by the interpreter in the same way as the applications
-When some event which should be catched by ABRT occurs and is detected
-by the hook, the hook reports it to ABRT using ABRT daemon's socket
-file. ABRT then creates a new directory describing the crash in
-/var/spool/abrt.
-
-The ABRT's CCpp plugin does not use the socket file, but it creates
-crash data directory in /var/spool/abrt directly. Interpreted hooks
-must not report crashes this way, because SELinux blocks interpreter
-access to /var/spool/abrt and this access can not be granted due to
-security issues.
-
-ABRT socket file resides in /var/run/abrt.socket. Hooks should open
-this socket for writing, write the event information, and close the
-socket. If the hook leaves the socket opened for a long time without
-writing anything, the ABRT daemon which listens on the other side will
-close the connection. The maximum number of concurrently opened socket
-sessions is also limited.
-
-The event data are sent to the socket in a number of fields in format
-"FIELDNAME=VALUE\0". Various fields impose various restrictions on the
-format of VALUE, but generally the VALUE might contain all characters
-except \0. Hook sends "DONE\0" after the last field to finish the
-entry creation process in the daemon. All fields are mandatory. Field
-order does not matter.
-
-Fields
-======
-
-PID
-Process id of the running interpreter.
-
-EXECUTABLE
-The file with the main entry point of the application. Might be a JAR
-archive, a script file, a bytecode file, or the interpreter. It should
-be a real file on the filesystem, so ABRT can check the origin of the
-file (source package). If the file is not known, the most appropriate
-is to shortly describe the reason why it is not known in the field.
-However, exceptions raised from interactive shell (a common reason
-for unknown file) are hardly useful and should not be reported.
-
-ANALYZER
-The name of an analyzer plugin which should be run during the
-analysis. It is used to choose appropriate method of post processing
-for the crash dump. Sensible names are "python", "perl",
"java" etc.
-
-BASENAME
-Short string indicating the origin of the event. It is used as a part
-of directory name: /var/spool/abrt/BASENAME-suffix. Use "python" for
-Python exceptions, "ruby" for ruby interpreter, "java" for JRE.
-
-REASON
-A short, one line string describing the event. For Python it is
-something like "CCMainWindow.py:1:<module>:ZeroDivisionError: integer
-division or modulo by zero".
-
-BACKTRACE
-The backtrace at the moment of the crash, if it is available. May
-include other useful information. For example, for ccpp crashes, it
-includes register dump. The backtrace should be in a format that is
-commonly used by the interpreter.
-
-Here is an example of a crash report from Python, as it is written to
-the socket:
-PID=563\0
-EXECUTABLE=/usr/bin/python\0
-ANALYZER=Python\0
-BASENAME=pyhook\0
-REASON=CReporterAssistant.py:415:on_plugin_toggled:ValueError: list.remove(x):
-x not in list\0
-BACKTRACE=Traceback (most recent call last):
- File "/usr/share/abrt/CReporterAssistant.py", line 415, in on_plugin_toggled
- self.selected_reporters.remove(reporter)
-ValueError: list.remove(x): x not in list
-
-Local variables in innermost frame:
-complete: False
-reporter: <ABRTPlugin.PluginInfo instance at 0x7fc7fb389050>
-self: <CReporterAssistant.ReporterAssistant instance at 0x7fc7fdc7acb0>
-plugin: <gtk.CheckButton object at 0x7fc7fdc8c9b0 (GtkCheckButton at 0x11d7ed0)>
-plugins: [<gtk.CheckButton object at 0x7fc7fdc8c9b0 (GtkCheckButton at
0x11d7ed0)>]
-page: <gtk.VBox object at 0x7fc7fdc8c460 (GtkVBox at 0x12f03b0)>\0
-DONE\0
diff --git a/doc/PLUGINS-HOWTO b/doc/PLUGINS-HOWTO
deleted file mode 100644
index 81090f3..0000000
--- a/doc/PLUGINS-HOWTO
+++ /dev/null
@@ -1,155 +0,0 @@
-This document describes how to create your own plugin for abrt.
-
-Although a base abstract class CPlugin exists, you can't inherit
-directly from it. You must use one of the four subclasses,
-depending on what you want your plugin to do.
-
-The subclasses are:
- * Action plugin (CAction)
- * Analyzer plugin (CAnalyzer)
- * Reporter plugin (CReporter)
- * Database plugin (CDatabase)
-
-Each of them requires you to override a different set of methods.
-
-The pDebugDumpDir parameter is very common: it specifies the directory
-that is created to gather information of this specific crash.
-The files that were created when the application crashed (such as core dumps)
-are all stored here. In addition, the plugins can write
-their output files there, if any.
-
-Plugin types in detail:
-
-
-Analyzer Plugin
----------------
-Crashes differ, depending on where they occur, for example crashes
-in the kernel differ from crashes in userspace binaries, which differ
-from crashes in python scripts. Therefore, there is a plugin
-for each type of application that you want abrt to handle.
-
-You have to override these methods:
-
-virtual std::string GetLocalUUID(const char *pDebugDumpPath);
-- This method is invoked immediately after crash is detected
- and its data is saved by the corresponding hook.
- It needs to compute an unique hash (UUID) of the crash.
- When a crash occurs and abrt finds an earlier crash with the same
- UUID, new crash is discarded as a duplicate, it doesn't show up
- in abrt's crash list, but instead a crash count for the earlier
- crash is incremented.
-
-virtual void CreateReport(const char *pDebugDumpDir, int force)
-- This method is called when user wants to report a crash
- ([Reoprt] button in GUI, etc). Analyzer can perform additional,
- more CPU/disk intensive, or interactive processing at this point.
- For example, CCpp plugin's CreateReport() processes coredump file,
- produces a textual backtrace, and saves it to crash dump directory.
-
-virtual std::string GetGlobalUUID(const char *pDebugDumpPath);
-- This method computes a "duplicate hash" which is used search for
- duplicates in remote bug databases such as Bugzilla. They are
- "less unique" than LocalUUIDs: ideally, the same crash
- on different architecture or with slightly different backtrace
- will still have the same GlobalUUID.
- [TODO: renaming it to DUPHASH]
-
-
-Action Plugin
--------------
-This type of plugin is useful when you need some action to be performed.
-Action plugins can be invoked in three ways:
-
-* Immediately when a crash is encountered (using ActionsAndReporters = ...
- directive in abrt.conf). These action plugins are run on every crash
- (regardless of crash type).
-
-* After Analyzer plugin processed a crash (by specifying plugin in
- [AnalyzerActionsAndReporters] section, for example: "CCpp =
AnActionPlugin").
- In this case, action plugin's Run() method will be run after analyzer
- plugin's CreateReport() and GetGlobalUUID() methods have finished.
-
-* If you need some action to be performed periodically ([Cron] section
- in the same file).
-
-You have to override one method:
-
-virtual void Run(const char *dir, const char *args);
-
-The first argument is a directory that contains the current debug
-dump, or all debug dumps for periodic actions.
-The second argument is a string with arguments (specified in config file).
-
-
-Reporter Plugin
----------------
-This plugin receives the entire finished crash report and
-posts/reports it somewhere (e.g. logs it, mails it, posts
-it on some web tool...)
-
-You have to override this method:
-
-virtual void Report(const map_crash_data_t& pCrashData,
- const char *pArgs);
-- This method takes the report and presents it somewhere to the world.
- The second argument is a string with arguments specified for the reporter.
-
-
-Database Plugin
----------------
-This plugin is used to store the metadata about the crash. The metadata
-has to be in a database, to distinguish whether the current crash is or
-is not the same as some crash before. The database can be local, or in
-some centralized location on the network.
-
-You have to override these methods:
-virtual void Connect();
-virtual void DisConnect();
-- connect and disconnect from the database
-
-virtual void Insert(const std::string& pUUID,
- const std::string& pUID,
- const std::string& pDebugDumpPath,
- const std::string& pTime);
-- insert an entry into the database: you use both UID (user ID) and UUID
- (ID of the crash)
-
-virtual void Delete(const std::string& pUUID, const std::string& pUID);
-- delete an entry
-
-virtual void SetReported(const std::string& pUUID, const std::string& pUID);
-- insert information into the database to say that this bug was already
- reported (so for example the report plugins won't run several times
- for the same bug)
-
-virtual const vector_database_rows_t GetUIDData(const std::string& pUID);
-- get database rows for the specified user ID
-
-virtual const database_row_t GetUUIDData(const std::string& pUUID, const
- std::string& pUID);
-- get a database row for the specified user ID and UUID
-
-
-The macro PLUGIN_INFO
----------------------
-Use the macro PLUGIN_INFO in the *.cpp file of your plugin so that your
-subclass will be properly registered and treated as a plugin.
-This sets up all the lower-level and administrative details to fit your
-class into the plugin infrastructure. The syntax is:
-
-PLUGIN_INFO(type, plugin_class, name, version, description, email, www)
-- "type" is one of ANALYZER, ACTION, REPORTER, or DATABASE
-- "plugin_class" is the identifier of the class
-- "name" is a string with the name of the plugin
-- "version" is a string with the version of the plugin
-- "description" is a string with the summary of what the plugin does
-- "email" and "www" are strings with the contact info for the author
-
-For example:
-PLUGIN_INFO(REPORTER,
- CMailx,
- "Mailx",
- "0.0.1",
- "Sends an email with a report via mailx command",
- "zprikryl(a)redhat.com",
- "https://fedorahosted.org/crash-catcher/wiki");
diff --git a/doc/coding-style b/doc/coding-style
new file mode 100644
index 0000000..3a254b7
--- /dev/null
+++ b/doc/coding-style
@@ -0,0 +1,64 @@
+Coding style used in abrt
+=================================
+
+1. Class
+--------
+1.1 Class has to start with 'C'
+
+1.2 Method
+-----------
+1.2.1 method starts witch a capital letter
+1.2.2 method name can contain only letters
+1.2.3 parameter of a method has to start with the letter 'p'
+
+1.3 Attribute
+-------------
+1.3.1 non-float attribute has to start with "m_n"
+1.3.2 float attribute has to start with "m_f"
+1.3.3 double attribute has to start with "m_d"
+1.3.4 bool attribute has to start with "m_b"
+1.3.5 string/char attribute has to start with "m_s"
+1.3.6 pointer attribute has to start with "m_p"
+1.3.7 template attribute has to start with a template name "m_map"
+1.3.8 otherwise "m_"
+
+2. Type
+-------
+2.1 every type has to end with "_t"
+2.2 types created from templates has to start with a template name
+2.3 words in a type has to be separated with "_"
+
+3. Statement
+------------
+3.1 "if", "while" and "for" has to have {} every time.
+3.2 { is on the new line every time
+
+4. Example
+----------
+
+typedef std::map<int, int> map_new_type_t;
+
+class CAwesomeClass
+{
+ private:
+ map_new_type_t m_NewType;
+ std::string m_sName;
+ COtherClass* m_pOtherClass;
+ void PrivateFunction(int pParameter);
+ public:
+ CAwesomeClass(std::string pName) :
+ m_sName(pName), m_pOtherClass(NULL)
+ {}
+};
+
+void CAwesomeClass::PrivateFunction(int pParameter)
+{
+ if (pParameter != "")
+ {
+ // do something
+ }
+ else
+ {
+ // do something else
+ }
+}
diff --git a/doc/design b/doc/design
new file mode 100644
index 0000000..6074457
--- /dev/null
+++ b/doc/design
@@ -0,0 +1,147 @@
+ Design goals
+
+We want to catch kernel oopses, binary program crashes (coredumps)
+and interpreted languages crashes (Python exceptions, maybe more
+in the future).
+
+We want to support the following use cases:
+
+* Home/office user with minimal administration
+
+In this scenario, user expects that abrt will work "out of the box"
+with minimal configuration. It will be sufficient if crashes
+just show a GUI notification, and user can invoke a GUI tool
+to process the crash and report it to bugzilla etc.
+
+The configuration (like bugzilla address, username, password)
+needs to be done via GUI dialogs from the same GUI tool.
+
+* Standalone server
+
+The server is installed by an admin. It may lack GUI.
+Admin is willing to do somewhat more complex configuration.
+Crashes should be recorded, and either processed at once
+or reported to the admin by email etc. Admin may log in
+and manually request crash(es) to be processed and reported,
+using GUI or CLI tools.
+
+* Mission critical servers, server farms etc.
+
+Admins are expected to be competent and willing to set up complex
+configurations. They might want to avoid any complex crash processing
+on the servers - for example, it does not make much sense and/or
+can be considered insecure to download debuginfo packages
+to such servers. Admins may want to send "raw" crash dumps
+to a dedicated server(s) for processing (backtrace, etc).
+
+
+ Design
+
+Abrt design should be flexible enough to accomodate all
+of the above usage scenarios.
+
+The description below is not what abrt does now.
+It is (currently incomplete) design notes on how we want
+it to achieve design goals.
+
+Since currently we do not know how to dump oops on demand,
+we can only poll for it. There is a small daemon which polls
+kernel message buffer and dumps oopses when it sees them.
+The dump is written into /var/spool/abrt/DIR.
+After this, daemon spawns "abrt-process -d /var/spool/abrt/DIR"
+which processes it according to configuration in /etc/abrt/*.conf.
+
+In order to catch binary crashes, we install a handler for it
+in /proc/sys/kernel/core_pattern (by setting it to
+"|/usr/libexec/abrt-hook-ccpp /var/spool/abrt %p %s %u").
+When process dumps core, the dump is written into /var/spool/abrt/DIR.
+After this, abrt-hook-ccpp spawns "abrt-process -d /var/spool/abrt/DIR"
+and terminates.
+
+When python program crashes, it invokes internel python subroutine
+which dumps crash info into ~/abrt/spool/DIR.
+[this is a tentative plan, currently we dump in /var/spool/abrt/DIR]
+After this, it spawns "abrt-process -d ~/abrt/spool/DIR"
+and terminates.
+
+[Problem: dumping to /var/spool/abrt/DIR needs world-writable
+/var/spool/abrt and allows user to go way over his
+disk quota. Dumping to ~/abrt/spool/DIR makes it difficult
+to present a list of all crashes which happened on the machine -
+for example, root-owned processes cannot even access user data
+in ~user/* if /home is on NFS4...
+]
+
+When user (admin) wants to see the list of dumped crashes and
+process them, he runs abrt-gui or abrt-cli. These programs
+perform a dbus call to "com.redhat.abrt" on a system dbus.
+If there is no program with this name on it, dbus autostart
+will invoke "abrt-process", which registers "com.redhat.abrt"
+and processes the call(s).
+
+abrt-process will terminate after a timeout (a few minutes)
+if no new dbus calls are arriving to it.
+
+The key dbus calls served by abrt-process are:
+
+- GetCrashInfos(): returns a vector_map_crash_data_t (vector_map_vector_string_t)
+ of crashes for given uid
+
v[N]["executable"/"uid"/"kernel"/"backtrace"][N] =
"contents"
+[see above the problem with producing this list]
+- CreateReport(UUID): starts creating a report for /var/spool/abrt/DIR with this UUID.
+ Returns job id (uint64).
+ After it returns, when report creation thread has finished,
+ JobDone(client_dbus_ID,UUID) dbus signal is emitted.
+ [Problem: how to do privilegged plugin specific actions?]
+ Solution: if plugin needs an access to some root only accessible dir then
+ abrt should be run by root anyway
+ - debuginfo gets installed using pk-debuginfo-install, which cares about
+ privileges itself, so no problem here
+- GetJobResult(UUID): returns map_crash_data_t (map_vector_string_t)
+- Report(map_crash_data_t (map_vector_string_t)):
+ "Please report this crash": calls Report() of all registered reporter
plugins
+ Returns report_status_t (map_vector_string_t) - the status of each call
+- DeleteDebugDump(UUID): delete corresponding /var/spool/abrt/DIR. Returns bool
+
+
+ Development plan
+
+Since current code does not match the planned design, we need to gradually
+change the code to "morph" it into the desired shape.
+
+Done:
+
+* Make abrtd dbus startable.
+* Add -t TIMEOUT_SEC option to abrtd. {done}
+* Make abrt-gui start abrtd on demand, so that abrt-gui can be started
+ even if abrtd does not run at the moment. (doesn't work in some cases!)
+
+Planned steps:
+
+* make kerneloops plugin into separate daemon (convert it to a hook
+ and get rid of "cron plugins" which are wrong idea since the begining)
+ - and make it to the service (write an initscript)
+* make C/C++ hook to be started by init script
+ - init scritp would run ccpp-hook --init whic shoudl just set the core_pattern, which
is now done by the C analyzer plugin
+* hooks will start the daemon on-demand using dbus
+ - this is something I'm not sure if it's good idea, but dbus is becoming
+ to be "un-installable" on Fedora, it's probably ok
+* simplify abrt.conf:
+ - move all plugin related info to plugins/<plugin>.conf
+ - enabled, action association, etc ...
+ - make abrtd to parse plugins/*.conf and set the config options
+ that it understand
+ - this will fix the case when this is in abrt.conf
+
+ [Cron]
+ KerneloopsScanner = 120
+
+ because this should be in plugins/kerneloops.conf
+ and thus shouldn't exist if kerneloops-addon is
+ not installed
+* ???
+* ???
+* ???
+* ???
+* ???
+* Take over the world
diff --git a/doc/how-to-test b/doc/how-to-test
new file mode 100644
index 0000000..425a2b3
--- /dev/null
+++ b/doc/how-to-test
@@ -0,0 +1,41 @@
+How to test before releasing new update:
+
+I. Build and install
+===================
+a) build the packages as scratch in koji
+b) download and install (the best is to create a local repo and try to install it using
yum)
+c) create a repository and try to update from previous packages
+d) start the daemon and check logs for any sign of a problem
+e) try to update from previous Fedora version using created repository
+
+II. Crash detection
+=====================
+ == 1. Default crash detection ==
+ a) kill some C/C++ app with kill -9 and watch if it's detected by abrt
+ b) edit some packaged python script to raise an exception and watch is abrt
+ detects it
+ c) use our saved kerneloopses and test detection of oopses
+
+ == 2. Advanced crash detection ==
+ a) crash some app that comes from unsigned package - abrt should ignore it
+ b) disable the gpg check and try repeat step a) - abrt shouldn't ignore it
+
+- try to add some crash-time action and test if it works
+
+III. Reporting
+=============
+ == 1. Reporting to bugzilla ==
+ a) try to report some crash to bz using gui
+ - gui should ask for login+pass
+ - crash should be reported after filling the right credentials
+ b) try to report using gui without gnome-keyring
+ - gui should ask for login+pass
+ - crash should be reported after filling the right credentials
+ - login+pass won't be saved
+ c) try to report every supported crash abrt detects C/C++, oops, python script
+ d) try to report some crash with bad backtrace - this should fail
+ e) repeat this with cli
+
+- test reporting with all reporters plugins like: ticketuploader, filetransport, etc..
+ repeating the step 'a' to 'e'
+
diff --git a/doc/implementation b/doc/implementation
new file mode 100644
index 0000000..72f12c7
--- /dev/null
+++ b/doc/implementation
@@ -0,0 +1,89 @@
+Implementation:
+
+C/C++ handling:
+==============
+
+we change /proc/sys/kernel/core_pattern to invoke abrtd helper to save
+the coredump of crashing app:
+* helper source code:
http://git.fedorahosted.org/git/abrt.git?p=abrt.git;a=blob_plain;f=src/Ho...
+the code responsible for this:
+
+ #define CORE_PATTERN "|/usr/libexec/abrt-hook-ccpp"
"/var/spool/abrt" %p %s %u"
+ ofstream fOutCorePattern;
+ fOutCorePattern.open(CORE_PATTERN_IFACE);
+ if (fOutCorePattern.is_open())
+ {
+ fOutCorePattern << CORE_PATTERN << endl;
+ fOutCorePattern.close();
+ }
+
+%p - pid
+%s - signal
+%u - uid
+
+when some crash occurs abrt-hook-ccpp is invoked to store the coredump and some other
info
+read from /proc/<pid>/:
+
+executable:
+ char buf[sizeof("/proc/%u/exe") + sizeof(int)*3];
+ sprintf(buf, "/proc/%u/exe", (int)pid);
+ readlink(buf);
+
+cmdline:
+ char path[sizeof("/proc/%u/cmdline") + sizeof(int)*3];
+ sprintf(path, "/proc/%u/cmdline", (int)pid);
+
+both is saved to file in /var/spool/abrt/ccpp-<time>-<pid> readable
+only by owner the crashed process:
+ int fd = open(pPath, O_WRONLY | O_TRUNC | O_CREAT, 0666);
+ if(fd){
+ do {
+ n = write(fd, buf, count);
+ } while (n < 0 && errno == EINTR);
+ }
+
+when the hook is done it signalize the daemon (be removing the lock file) and
+daemon process the written info and saves some aditional information:
+ analyzer : name of the plugin used to analyze the crash (ccpp, python)
+ component : source package name
+ description : package description (will be removed soon)
+ kernel : kernel version
+ release : Fedora release string
+ uid : uid of the owner of the crashed app
+ architecture : architecture (i386, x86_64,etc)
+ package : package name
+ reason : e.g "Process was terminated by signal 11 (Segmentation
fault)"
+ time : unix time of the crash
+
+2. send dbus signal (broadcast) about new crash, this signal contains two informations:
+ 1. uid of the app owner
+ 2. package name
+
+This is all what happens when some app crashes, the next step is to process
+the coredump and extract the backtrace. This is done on user demand by calling
+getReport(UUID) method or automatically if admin sets it in /etc/abrt/abrt.conf
+* UUID is unique id of the crash in the database, every user is allowed to see only
+ his own crashes or kerneloops crashes
+- see
http://git.fedorahosted.org/git/abrt.git?p=abrt.git;a=blob;f=lib/Plugins/... line
394
+ for more details
+
+1. processing coredump:
+ a) determine if the crashed binary belongs to some installed package
+ if it does then:
+ b) daemon tries to install the debuginfo issuing this command:
+
+execlp("abrt-debuginfo-install", "abrt-debuginfo-install", coredump,
tempdir, debuginfo_dirs, NULL);
+
+abrt-debuginfo-install is a shell script using elfutils to get build-ids from coredump
and the use
+"yum provides" and "yumdownloader" to determine and download the
missing debuginfo packages
+* script source code:
http://git.fedorahosted.org/git/abrt.git?p=abrt.git;a=blob_plain;f=src/Da...
+ c) run gdb and get backtrace from coredump:
+ see
http://git.fedorahosted.org/git/abrt.git?p=abrt.git;a=blob_plain;f=lib/Pl...
line 260
+ - gdb is run with the same privileges as the crashed app (setregid, setreuid)
+ d) BT is saved to same directory where the coredump is
+
+Once the backtrace is processed all data from the
/var/spool/abrt/ccpp-<time>-<pid> is sent
+over dbus to the client and then user can edit the backtrace. When user is happy about
+the report and command the client (gui, tui) to send the it, the client sends the data
back
+to the daemon calling the Report(data) method over the dbus. The actual reporting is done
by
+the respective plugin which is loaded in daemon.
diff --git a/doc/interpreted-languages b/doc/interpreted-languages
new file mode 100644
index 0000000..e79a132
--- /dev/null
+++ b/doc/interpreted-languages
@@ -0,0 +1,113 @@
+This document describes the interaction between ABRT and interpreted
+languages.
+
+Interpreted language is a programming language where the programs
+written in that language are not translated into the machine code of
+the computer it is on, but interpreted by another software program
+known as an interpreter.
+
+In order to handle interpreted language correctly, ABRT needs a hook
+in the language's interpreter. The hook catches serious application
+misbehaviors (such as uncaught exceptions, invalid bytecode, missing
+library) inside the interpreter and reports the misbehaviors to
+ABRT. Hook is usually responsible for assembling the backtrace.
+
+Another issue are the crashes of the interpreter, which are catched by
+the CCpp plugin. When the support for specific interpreter is missing
+all these crashes are reported to the interpreter component when
+submitting the crash using Bugzilla plugin, regardless of application
+executed by the interpreter. To change this, the interpreter should be
+handled in src/Daemon/MiddleWare.cpp (see how it is done for Python).
+
+ABRT currently support only CPython interpreter (the mainstream Python
+implementation). Perl, Java, Ruby, and Mono interpreter hooks are yet
+to be written. It might be necessary to modify ABRT to support a new
+interpreter (patches welcomed).
+
+Communication between ABRT and hooks
+====================================
+
+Hook might be a binary plugin plugged to the interpreter, or it might
+be interpreted by the interpreter in the same way as the applications
+When some event which should be catched by ABRT occurs and is detected
+by the hook, the hook reports it to ABRT using ABRT daemon's socket
+file. ABRT then creates a new directory describing the crash in
+/var/spool/abrt.
+
+The ABRT's CCpp plugin does not use the socket file, but it creates
+crash data directory in /var/spool/abrt directly. Interpreted hooks
+must not report crashes this way, because SELinux blocks interpreter
+access to /var/spool/abrt and this access can not be granted due to
+security issues.
+
+ABRT socket file resides in /var/run/abrt.socket. Hooks should open
+this socket for writing, write the event information, and close the
+socket. If the hook leaves the socket opened for a long time without
+writing anything, the ABRT daemon which listens on the other side will
+close the connection. The maximum number of concurrently opened socket
+sessions is also limited.
+
+The event data are sent to the socket in a number of fields in format
+"FIELDNAME=VALUE\0". Various fields impose various restrictions on the
+format of VALUE, but generally the VALUE might contain all characters
+except \0. Hook sends "DONE\0" after the last field to finish the
+entry creation process in the daemon. All fields are mandatory. Field
+order does not matter.
+
+Fields
+======
+
+PID
+Process id of the running interpreter.
+
+EXECUTABLE
+The file with the main entry point of the application. Might be a JAR
+archive, a script file, a bytecode file, or the interpreter. It should
+be a real file on the filesystem, so ABRT can check the origin of the
+file (source package). If the file is not known, the most appropriate
+is to shortly describe the reason why it is not known in the field.
+However, exceptions raised from interactive shell (a common reason
+for unknown file) are hardly useful and should not be reported.
+
+ANALYZER
+The name of an analyzer plugin which should be run during the
+analysis. It is used to choose appropriate method of post processing
+for the crash dump. Sensible names are "python", "perl",
"java" etc.
+
+BASENAME
+Short string indicating the origin of the event. It is used as a part
+of directory name: /var/spool/abrt/BASENAME-suffix. Use "python" for
+Python exceptions, "ruby" for ruby interpreter, "java" for JRE.
+
+REASON
+A short, one line string describing the event. For Python it is
+something like "CCMainWindow.py:1:<module>:ZeroDivisionError: integer
+division or modulo by zero".
+
+BACKTRACE
+The backtrace at the moment of the crash, if it is available. May
+include other useful information. For example, for ccpp crashes, it
+includes register dump. The backtrace should be in a format that is
+commonly used by the interpreter.
+
+Here is an example of a crash report from Python, as it is written to
+the socket:
+PID=563\0
+EXECUTABLE=/usr/bin/python\0
+ANALYZER=Python\0
+BASENAME=pyhook\0
+REASON=CReporterAssistant.py:415:on_plugin_toggled:ValueError: list.remove(x):
+x not in list\0
+BACKTRACE=Traceback (most recent call last):
+ File "/usr/share/abrt/CReporterAssistant.py", line 415, in on_plugin_toggled
+ self.selected_reporters.remove(reporter)
+ValueError: list.remove(x): x not in list
+
+Local variables in innermost frame:
+complete: False
+reporter: <ABRTPlugin.PluginInfo instance at 0x7fc7fb389050>
+self: <CReporterAssistant.ReporterAssistant instance at 0x7fc7fdc7acb0>
+plugin: <gtk.CheckButton object at 0x7fc7fdc8c9b0 (GtkCheckButton at 0x11d7ed0)>
+plugins: [<gtk.CheckButton object at 0x7fc7fdc8c9b0 (GtkCheckButton at
0x11d7ed0)>]
+page: <gtk.VBox object at 0x7fc7fdc8c460 (GtkVBox at 0x12f03b0)>\0
+DONE\0
diff --git a/doc/plugins-howto b/doc/plugins-howto
new file mode 100644
index 0000000..81090f3
--- /dev/null
+++ b/doc/plugins-howto
@@ -0,0 +1,155 @@
+This document describes how to create your own plugin for abrt.
+
+Although a base abstract class CPlugin exists, you can't inherit
+directly from it. You must use one of the four subclasses,
+depending on what you want your plugin to do.
+
+The subclasses are:
+ * Action plugin (CAction)
+ * Analyzer plugin (CAnalyzer)
+ * Reporter plugin (CReporter)
+ * Database plugin (CDatabase)
+
+Each of them requires you to override a different set of methods.
+
+The pDebugDumpDir parameter is very common: it specifies the directory
+that is created to gather information of this specific crash.
+The files that were created when the application crashed (such as core dumps)
+are all stored here. In addition, the plugins can write
+their output files there, if any.
+
+Plugin types in detail:
+
+
+Analyzer Plugin
+---------------
+Crashes differ, depending on where they occur, for example crashes
+in the kernel differ from crashes in userspace binaries, which differ
+from crashes in python scripts. Therefore, there is a plugin
+for each type of application that you want abrt to handle.
+
+You have to override these methods:
+
+virtual std::string GetLocalUUID(const char *pDebugDumpPath);
+- This method is invoked immediately after crash is detected
+ and its data is saved by the corresponding hook.
+ It needs to compute an unique hash (UUID) of the crash.
+ When a crash occurs and abrt finds an earlier crash with the same
+ UUID, new crash is discarded as a duplicate, it doesn't show up
+ in abrt's crash list, but instead a crash count for the earlier
+ crash is incremented.
+
+virtual void CreateReport(const char *pDebugDumpDir, int force)
+- This method is called when user wants to report a crash
+ ([Reoprt] button in GUI, etc). Analyzer can perform additional,
+ more CPU/disk intensive, or interactive processing at this point.
+ For example, CCpp plugin's CreateReport() processes coredump file,
+ produces a textual backtrace, and saves it to crash dump directory.
+
+virtual std::string GetGlobalUUID(const char *pDebugDumpPath);
+- This method computes a "duplicate hash" which is used search for
+ duplicates in remote bug databases such as Bugzilla. They are
+ "less unique" than LocalUUIDs: ideally, the same crash
+ on different architecture or with slightly different backtrace
+ will still have the same GlobalUUID.
+ [TODO: renaming it to DUPHASH]
+
+
+Action Plugin
+-------------
+This type of plugin is useful when you need some action to be performed.
+Action plugins can be invoked in three ways:
+
+* Immediately when a crash is encountered (using ActionsAndReporters = ...
+ directive in abrt.conf). These action plugins are run on every crash
+ (regardless of crash type).
+
+* After Analyzer plugin processed a crash (by specifying plugin in
+ [AnalyzerActionsAndReporters] section, for example: "CCpp =
AnActionPlugin").
+ In this case, action plugin's Run() method will be run after analyzer
+ plugin's CreateReport() and GetGlobalUUID() methods have finished.
+
+* If you need some action to be performed periodically ([Cron] section
+ in the same file).
+
+You have to override one method:
+
+virtual void Run(const char *dir, const char *args);
+
+The first argument is a directory that contains the current debug
+dump, or all debug dumps for periodic actions.
+The second argument is a string with arguments (specified in config file).
+
+
+Reporter Plugin
+---------------
+This plugin receives the entire finished crash report and
+posts/reports it somewhere (e.g. logs it, mails it, posts
+it on some web tool...)
+
+You have to override this method:
+
+virtual void Report(const map_crash_data_t& pCrashData,
+ const char *pArgs);
+- This method takes the report and presents it somewhere to the world.
+ The second argument is a string with arguments specified for the reporter.
+
+
+Database Plugin
+---------------
+This plugin is used to store the metadata about the crash. The metadata
+has to be in a database, to distinguish whether the current crash is or
+is not the same as some crash before. The database can be local, or in
+some centralized location on the network.
+
+You have to override these methods:
+virtual void Connect();
+virtual void DisConnect();
+- connect and disconnect from the database
+
+virtual void Insert(const std::string& pUUID,
+ const std::string& pUID,
+ const std::string& pDebugDumpPath,
+ const std::string& pTime);
+- insert an entry into the database: you use both UID (user ID) and UUID
+ (ID of the crash)
+
+virtual void Delete(const std::string& pUUID, const std::string& pUID);
+- delete an entry
+
+virtual void SetReported(const std::string& pUUID, const std::string& pUID);
+- insert information into the database to say that this bug was already
+ reported (so for example the report plugins won't run several times
+ for the same bug)
+
+virtual const vector_database_rows_t GetUIDData(const std::string& pUID);
+- get database rows for the specified user ID
+
+virtual const database_row_t GetUUIDData(const std::string& pUUID, const
+ std::string& pUID);
+- get a database row for the specified user ID and UUID
+
+
+The macro PLUGIN_INFO
+---------------------
+Use the macro PLUGIN_INFO in the *.cpp file of your plugin so that your
+subclass will be properly registered and treated as a plugin.
+This sets up all the lower-level and administrative details to fit your
+class into the plugin infrastructure. The syntax is:
+
+PLUGIN_INFO(type, plugin_class, name, version, description, email, www)
+- "type" is one of ANALYZER, ACTION, REPORTER, or DATABASE
+- "plugin_class" is the identifier of the class
+- "name" is a string with the name of the plugin
+- "version" is a string with the version of the plugin
+- "description" is a string with the summary of what the plugin does
+- "email" and "www" are strings with the contact info for the author
+
+For example:
+PLUGIN_INFO(REPORTER,
+ CMailx,
+ "Mailx",
+ "0.0.1",
+ "Sends an email with a report via mailx command",
+ "zprikryl(a)redhat.com",
+ "https://fedorahosted.org/crash-catcher/wiki");
--
1.7.1