PYTHON3-ABRT(5)
π PYTHON3-ABRT(5) π
okay bestie, sit down, hydrate, because we're about to get into python3-abrt β yes that's the manual name, PYTHON3-ABRT(5), and it's so much more fun than it sounds, trust.
πΈ NAME πΈ
python3-abrt β the python3-abrt documentation. Slay, we love a self-referential queen.
It's the high-level API for querying, creating and manipulating problems handled by ABRT, in Python. So instead of poking at raw bytes like a Victorian orphan, you get nice Python objects. π¦
How does it work under the hood, you ask? It sits on top of the low-level DBus or socket API that ABRT provides. And the socket API? Bestie, it's a fallback. It only exists for systems that don't have the new DBus problem API, and it can only handle creating new problems. That's it. That's all it does. It's giving side quest. π
This project lives in the abrt repository and is distributed under GPLv2</> license. FOSS royalty, no cap. π
Contents:
β¨ USAGE EXAMPLES β¨
π Creating new problem
import problem
prob = problem.Runtime(
reason='egg_error_message: assertion "error" failed',
)
prob.add_current_process_data()
prob.add_current_environment()
prob.save()
Look at her. problem.Runtime, a reason, grab the current process data and environment, then save(). Iconic. π
π Creating problem for different executable
import problem
prob = problem.Selinux(reason='Front fell off')
prob.executable = '/usr/bin/time'
prob.save()
Notice how we just set prob.executable to whatever we want. '/usr/bin/time' in this case. "Front fell off" as a reason is genuinely the most valid bug report I've ever read. π
π Adding custom data
import problem
prob = problem.Runtime(
reason='Error getting devices:'
'GDBus.Error:org.freedesktop.DBus.Error.UnknownMethod: '
'No such interface `org.gnome.SettingsDaemon.Power` on object at path '
'/org/gnome/SettingsDaemon/Power'
)
prob.add_current_process_data()
prob.custom_data = 'any'
prob['dict_access_example'] = 'works'
print(prob)
print('')
for key, value in prob.items():
print('{0}={1}'.format(key, value))
print('Identifier:', prob.save())
The way that prob.custom_data = 'any' works and prob['dict_access_example'] = 'works' works?? Two whole ways to set stuff. Highkey obsessed. Also peep the multi-line implicit string concat in the reason β that's just Python being pretty. β¨
π Querying problems
import problem
for prob in problem.list():
print(prob)
print(repr(prob.time))
if hasattr(prob, 'pid'):
print(prob.pid)
problem.list() gives you the goods, and hasattr(prob, 'pid') is your vibe check before you touch it. Never assume a field exists, bestie. That's how you get an AttributeError in front of everyone. π
π Querying all problems
The list method used with the auth=True parameter will try to authenticate via polkit</> to gain access to all problems on the system. Queen behavior, going for the whole system.
If there is no authentication agent running, or authentication is unsuccessful, the list of problems which belong to the current user is returned β same as returned by the plain list method. So no drama, you just get your own stuff back. π«Ά
import problem
for prob in problem.list(auth=True):
print(prob)
if hasattr(prob, 'username'):
print('Problem belongs to {0}'.format(prob.username))
π Editing existing problems
import problem
for prob in problem.list():
if prob.type == problem.JAVA:
prob.delete()
if prob.type == problem.CCPP:
if 'password' in prob.backtrace:
del prob.backtrace
prob.save()
if prob.type == problem.KERNELOOPS:
prob.backtrace = prob.backtrace.replace(' ?', '')
prob.save()
Three little branches, three little moods: delete it, scrub the password out and save, tidy the backtrace and save. That's the whole personality of this example and I respect it.
π Watching for new problems
import problem
import logging
logging.basicConfig(level=logging.DEBUG)
def monitor(prob):
print(prob)
prob.delete()
pwatch = problem.get_problem_watcher()
pwatch.add_callback(monitor)
try:
pwatch.run()
except KeyboardInterrupt:
pwatch.quit()
logging.basicConfig(level=logging.DEBUG) so you can see everything, then run() forever until you smash Ctrl+C, at which point KeyboardInterrupt catches it and pwatch.quit() lets you leave gracefully. Manners! π
π Watching for new problems in a thread
from __future__ import print_function
import sys
import time
import problem
import threading
class ProblemWatchThread(threading.Thread):
def __init__(self):
super(ProblemWatchThread, self).__init__()
self.pwatch = problem.get_problem_watcher()
self.pwatch.add_callback(self.handle)
self.probcount = 0
def handle(self, prob):
self.probcount += 1
print('{0}: {1}'.format(self.probcount, prob))
# prob.delete()
def run(self):
self.pwatch.run()
def stop(self):
self.pwatch.quit()
pwt = ProblemWatchThread()
pwt.start()
i = 0
print('Waiting for new problem to appear')
spinner = ['\\', '|', '/', '-']
try:
while True:
time.sleep(0.1)
print('{0}\r'.format(spinner[i]), end='')
i += 1
i = i % len(spinner)
sys.stdout.flush()
except KeyboardInterrupt:
pwt.stop()
pwt.stop()
THE SPINNER?? ['\\', '|', '/', '-'] β a whole rotating loader in a terminal, with \r and sys.stdout.flush() and everything. It's giving main character energy. π₯ Note the # prob.delete() is commented out, so nothing gets nuked while you're watching. And yes, from __future__ import print_function is there, it's ancient lore, don't touch it.
π Getting bug numbers of problems reported to bugzilla
import problem
bugs = set()
for prob in problem.list():
if not hasattr(prob, 'reported_to'):
continue
for line in prob.reported_to.splitlines():
if line.startswith('Bugzilla:'):
bug_num = int(line.split('=')[-1])
bugs.add(bug_num)
print(bugs)
A set so no dupes, hasattr so no crashes, splitlines() then startswith('Bugzilla:') then split('=')[-1] and int() it. Textbook. You ate that. π
π STABLE API DOCUMENTATION π
π class problem.Problem(typ, reason, analyzer=None)
Base class for the other problem types.
No need to use this class directly, bestie β use one of the specific problem classes instead. This is the ancestor, not the moment. β¨
add_current_environment()β Add environment of current process to this problem objectadd_current_process_data()β Addpid,gidandexecutableof current process to this problem objectchown()β Assures ownership of a problem for the callerdelete()β Delete this problemprefetch_data()β Prefetch possible data fields of this problemsave()β Create this problem or update modified data
On that save() β here's the tea. It creates or updates the project if some of its fields were modified.
It returns None in case of modification, and the identifier if a new problem was created. So if you get None back, that's not a bug, that's a success, it just means you modified instead of created. Read the return value, bestie. π
π problem.get(identifier, auth=False)
Return problem object matching identifier.
Returns None in case the problem does not exist. Use auth=True if authentication should be attempted.
π problem.get_problem_watcher(auth=False)
Return ProblemWatcher object which can be used to attach callbacks called when a new problem is created.
Use auth=True if authentication should be attempted for new problems that don't belong to the current user. If not set, such a problem is ignored. So like, if you're nosy, pass the True. π
π problem.list(auth=False)
Return the list of the problems.
Use auth=True if authentication should be attempted.
If authentication via polkit</> fails, the function behaves as if auth=False was specified β only users' problems are returned. No exception, no drama, just a quiet downgrade. π«Ά
π Specific problem types π
class problem.Ccpp(reason)β C, C++ problemclass problem.Java(reason)β Java problemclass problem.Kerneloops(reason)β Kerneloops problemclass problem.Python(reason)β Python problemclass problem.Python3(reason)β Python3 problemclass problem.Runtime(reason)β Runtime problemclass problem.Selinux(reason)β Selinux problemclass problem.Unknown(reason)β Unknown problemclass problem.Xorg(reason)β Xorg problem
Pick your fighter. They all take a reason. That's the whole bit and it's a good bit. π¦
π§ ProblemWatcher π§
class problem.watch.ProblemWatcher(auth)
New problem signal handler attached to DBus signal.
Use auth=True if authentication should be attempted for new problems that don't belong to the current user. If not set, such a problem is ignored. (Same energy as get_problem_watcher, because that's literally where you get one of these from.)
add_callback(fun)β Add callback to be called when new problem occurs.
Each callback function receives a Problem instance. π
quit()β Stop event listener looprun()β Start event listener loop
run() starts it, quit() stops it, and in between your callbacks get fed Problem instances. That's the whole loop, and it's lowkey perfect. β¨
π PROBLEM OBJECT PROPERTIES π
okay so here's the tea on problem properties: right now there is literally no strict specification of what a problem property has to be. You are free to add your own data as you see fit β log files, process data, whatever β as long as you're planning to use them for reporting. Slay, it's your house π β¨
π Mandatory properties required prior saving π
These ones you MUST have before you save, no cap:
executableβ the executable path of the component which caused the problem. Example:'/usr/bin/time'. The server uses this to determine the component and package data. So like, it's giving main character energy for a reason π
π¦ Properties the server adds when a new problem is created π¦
Not you doing everything yourself β the server pulls up and drops these in for you, bestie:
componentβ the component which caused this problem. Example:'time'hostnameβ hostname of the affected machine. Example:'fiasco'os_releaseβ operating system release string. Example:'Fedora release 17 (Beefy Miracle)'uidβ user ID. Example:1000usernameβ example:'jeff'architectureβ machine architecture string. Example:'x86_64'kernelβ kernel version string. Example:'3.6.6-1.fc17.x86_64'packageβ package string. Example:'time-1.7-40.fc17.x86_64'timeβ time of the occurrence (unixtime). Example:datetime.datetime(2012, 12, 2, 16, 18, 41)countβ number of times this problem occurred. Example:1
π Parsed package data π
and there's also the parsed package data just sitting there, ready for you, periodt:
pkg_nameβ package name. Example:'time'pkg_epochβ package epoch. Example:0pkg_versionβ package version. Example:'1.7'pkg_releaseβ package release. Example:'40.fc17'pkg_archβ package architecture. Example:'x86_64'
β¨ Other common properties β¨
these are the other common ones, and lowkey their presence differs based on problem type β so don't come for me if one's missing, it's just the vibe check of whichever type you got π«Ά
abrt_versionβ ABRT version string. Example:'2.0.18.84.g211c'. Applicable to: crashes caught by ABRT.cgroupβ cgroup (control group) information for crashed process. Example:'9:perf_event:/\n8:blkio:/\n...'. Applicable to: C/C++.core_backtraceβ machine readable backtrace with no private data. Applicable to: C/C++, Python, Ruby, Kerneloops.backtraceβ original backtrace or backtrace produced by retracing process. Applicable to: C/C++ (after retracing), Python, Ruby, Xorg, Kerneloops.dso_listβ list of dynamic libraries loaded at the time of crash. Applicable to: C/C++, Python.mapsβ a whole copy of the/proc/<pid>/mapsfile for the problem executable π produced by C/C++.cmdlineβ copy of the/proc/<pid>/cmdlinefile, defaulting to'/usr/bin/gtk-builder-convert'. Comes from C/C++, Python, Ruby and Kerneloops. πΈcoredumpβ the actual coredump of the crashing process. C/C++ only, bestie, it's giving main character energy πenvironβ the runtime environment of the process, captured as it was. C/C++ and Python. β¨open_fdsβ the list of file descriptors that were open at the exact time of the crash. C/C++. π«Άpidβ the Process ID, defaulting to'42'. Brought to you by C/C++, Python and Ruby. π₯proc_pid_statusβ a copy of the/proc/<pid>/statusfile. C/C++. πlimitsβ a copy of the/proc/<pid>/limitsfile. C/C++. πvar_log_messagesβ the part of the/var/log/messagesfile that holds the crash information. C/C++. π¦suspend_statsβ a copy of/sys/kernel/debug/suspend_stats. Kerneloops energy. πreported_toβ if the problem was already reported, this item holds the URLs of the services where it got reported. That's Reported problems coded. πevent_logβ the ABRT event log. Also Reported problems. βdmesgβ a copy ofdmesg. Kerneloops coded. π
β¨ Index β¨
- Index
- Module Index
- Search Page
ngl bestie, those three are just the standard navigation links from the docs build β click away, they're not deep lore π
πΈ AUTHOR πΈ
Richard Marko
π COPYRIGHT π
2012, Richard Marko
okay that's a wrap, bestie!! π«Ά this whole thing was served up as version 0.1, dated Aug 03, 2026, and it's the PYTHON3-ABRT(5) page. go forth and debug slayfully π
β¨
π¦ where this page comes from
- fedora 43: python3-abrt 2.17.9-1.fc43 Β· GPL-2.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms