Portál AbcLinuxu, 3. května 2025 14:59

CryoPID - zmražte procesy s horkou hlavou

10.9.2009 01:36 | Přečteno: 1192× | programování | poslední úprava: 17.11.2009 21:33

Jednou jsem ladil pythoní program s race condition, která se vyskytovala výjimečně (pravděpodobnost cca 1:1000-1:100) když bylo spuštěno mnoho instancí daného programu paralelně. Identifikovat moment, kdy se invariant porušil nebylo těžký, jenže zalogování nestačilo - a python nemá nástroj pro "ekvivalent" coredumpu, který by se pak později mohl prohlédnut debuggerem.

Po delším googlení jsem narazil na projekt CryoPID, který umí zmrazit proces do ELF binárky na disku (ta pak pokračuje od momentu zmražení). Přeložit to nebylo nic snadné (nadával jsem než se mi to povedlo zprovoznit přes různé hacky).

Download

Binárky a ohackované zdrojáky mají původ v momentálním mercurial tip (7da69201d50e).

Bohužel i386/i686 binárky nemám, protože po překladu v 32bit chrootu nefungovaly. (Starší předkompilované binárky je možné stáhnout ze stránky projektu).

Přenositelnost cryopid

Vzhledem k tomu, že se cryopid linkuje jenom proti libz a glibc, mělo by to fungovat všude. Vyzkoušel jsem to na Gentoo glibc 2.8, Debianu Lenny a Etch. S Debianem problém nebyl, na Gentoo z nějakého důvodu nešlo obnovit zmraženy python2.5 procesy. Python 2.4 a 2.6 byly ok, spíš než na verzi jádra bych to tipoval na verzi knihoven. Segfault od zmraženého python2.5 procesu byl tak hustý, že i gdb lakonicky zahlásilo "Process no longer exists".

Holt CryoPID není dokonalý, ale smekám proti tomu co umí.

Ohackované zdrojáky obsahují copy-and-pastnuté definice maker _syscall2 a _syscall4, které myslím od jádra 2.6.20 nejsou součástí kernel-headers (nebo kernelu samotného). Podobně pro i686 bude nejspíš stačit nadefinovat (copy-and-pastovat syscall kód přes int 0x80). Příliš do kernel developmentu nevidím, pokud víte jak nahradit tyhle makra, neváhejte se ozvat.

Makefile-y ohackovaných zdrojáků obsahují include /usr/src/linux, tudíž pro úspěšný překlad buď musíte mít zdrojáky jádra nebo kompatilní kernel-headers.

Zmrazování při detekci porušení invariantu při race condition (příklad)

Pozn: já používám Komodo IDE remote debugger (dbgp.client, metoda brk), ale klidně by šlo použít třeba na winpdb nebo jiný debugger. Pointa zmražení je, že "odmražený" spuštený proces se rovnou připojí k debuggeru.

#!/usr/bin/env python

import sys

sys.path.append("/opt/Komodo/")

from dbgp.client import brk

import os
import subprocess
import time

class A(object):
    def __init__(self, **kwargs):
	self.__dict__.update(kwargs)
    def __str__(self):
	return str([(k, v) for (k, v) in self.__dict__.iteritems()])

a = A(a=1, b=2, c="c")

#Tady je nejaky test kde se zjisti ze se neco rozbilo a nedava smysl.
#Kdyz se neco rozbilo, zavolame fork a freeznem childa

pid = os.fork()
if pid > 0: #parent
    argv = ["/home/ondro/bin/cryopid", "-l", "child.cryo", str(pid)] 
    p = subprocess.Popen(argv, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    l = p.communicate()
    p.wait()
    print l[0]
    print l[1]

    print "Freeze finished"
    sys.exit(0)
elif pid == 0: #child

    time.sleep(5) #chceme se vyhnout race condition nez se proces zmrazi, systemovy semget() by byl lepsi
    brk(host="localhost", port=9000)
    for i in range(5):
	print "Sleeping: ", i
	time.sleep(1)

    print a
else:
    print "Fork failed"

Checkpointing software

Když vás zajímjí podobné postupy, podívejte se na Checkpointing software.

       

Hodnocení: 100 %

        špatnédobré        

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

Komentáře

Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře. , Tisk

Vložit další komentář

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.