mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-22 18:07:57 +00:00
Add support for python3 in criu-coredump
Resolve the following python3 portability issues: 1) Python 3 needs explicit relative import path. 2) Coredumps are binary data, not unicode strings. Use byte strings (b"" instead of "") and open files in binary format. 3) Some functions (for example: filter) return a list in python 2, but an iterator in python 3. Port code to a common subset of python 2 and python 3 using itertool. 4) Division operator / changed meaning in Python 3. Use explicit integer division (//) where appropriate. Signed-off-by: Andrey Vyazovtsev <viazovtsev.av@phystech.edu>
This commit is contained in:
parent
f24360658f
commit
3180d35fa4
@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/env python2
|
#!/usr/bin/env python
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
|
|
||||||
@ -10,7 +10,7 @@ def coredump(opts):
|
|||||||
for pid in cores:
|
for pid in cores:
|
||||||
if opts['pid'] and pid != opts['pid']:
|
if opts['pid'] and pid != opts['pid']:
|
||||||
continue
|
continue
|
||||||
with open(os.path.realpath(opts['out'])+"/core."+str(pid), 'w+') as f:
|
with open(os.path.realpath(opts['out'])+"/core."+str(pid), 'wb+') as f:
|
||||||
cores[pid].write(f)
|
cores[pid].write(f)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
from coredump import *
|
from .coredump import *
|
||||||
import elf
|
from . import elf
|
||||||
|
@ -29,9 +29,14 @@
|
|||||||
# 4) VMAs contents;
|
# 4) VMAs contents;
|
||||||
#
|
#
|
||||||
import io
|
import io
|
||||||
import elf
|
import sys
|
||||||
|
from . import elf
|
||||||
import ctypes
|
import ctypes
|
||||||
from pycriu import images
|
from pycriu import images
|
||||||
|
try:
|
||||||
|
from itertools import ifilter as filter
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
# Some memory-related constants
|
# Some memory-related constants
|
||||||
PAGESIZE = 4096
|
PAGESIZE = 4096
|
||||||
@ -88,7 +93,7 @@ class coredump:
|
|||||||
for note in self.notes:
|
for note in self.notes:
|
||||||
buf.write(note.nhdr)
|
buf.write(note.nhdr)
|
||||||
buf.write(note.owner)
|
buf.write(note.owner)
|
||||||
buf.write("\0" * (8 - len(note.owner)))
|
buf.write(b"\0" * (8 - len(note.owner)))
|
||||||
buf.write(note.data)
|
buf.write(note.data)
|
||||||
|
|
||||||
offset = ctypes.sizeof(elf.Elf64_Ehdr())
|
offset = ctypes.sizeof(elf.Elf64_Ehdr())
|
||||||
@ -136,7 +141,7 @@ class coredump_generator:
|
|||||||
path += "-" + str(pid)
|
path += "-" + str(pid)
|
||||||
path += ".img"
|
path += ".img"
|
||||||
|
|
||||||
with open(path) as f:
|
with open(path, 'rb') as f:
|
||||||
img = images.load(f)
|
img = images.load(f)
|
||||||
|
|
||||||
if single:
|
if single:
|
||||||
@ -177,7 +182,7 @@ class coredump_generator:
|
|||||||
for p in self.coredumps:
|
for p in self.coredumps:
|
||||||
if pid and p != pid:
|
if pid and p != pid:
|
||||||
continue
|
continue
|
||||||
with open(coredumps_dir + "/" + "core." + str(p), 'w+') as f:
|
with open(coredumps_dir + "/" + "core." + str(p), 'wb+') as f:
|
||||||
self.coredumps[p].write(f)
|
self.coredumps[p].write(f)
|
||||||
|
|
||||||
def _gen_coredump(self, pid):
|
def _gen_coredump(self, pid):
|
||||||
@ -295,7 +300,7 @@ class coredump_generator:
|
|||||||
prpsinfo.pr_state = 3
|
prpsinfo.pr_state = 3
|
||||||
# Don't even ask me why it is so, just borrowed from linux
|
# Don't even ask me why it is so, just borrowed from linux
|
||||||
# source and made pr_state match.
|
# source and made pr_state match.
|
||||||
prpsinfo.pr_sname = '.' if prpsinfo.pr_state > 5 else "RSDTZW" [
|
prpsinfo.pr_sname = b'.' if prpsinfo.pr_state > 5 else b"RSDTZW" [
|
||||||
prpsinfo.pr_state]
|
prpsinfo.pr_state]
|
||||||
prpsinfo.pr_zomb = 1 if prpsinfo.pr_state == 4 else 0
|
prpsinfo.pr_zomb = 1 if prpsinfo.pr_state == 4 else 0
|
||||||
prpsinfo.pr_nice = core["thread_core"][
|
prpsinfo.pr_nice = core["thread_core"][
|
||||||
@ -307,8 +312,12 @@ class coredump_generator:
|
|||||||
prpsinfo.pr_ppid = pstree["ppid"]
|
prpsinfo.pr_ppid = pstree["ppid"]
|
||||||
prpsinfo.pr_pgrp = pstree["pgid"]
|
prpsinfo.pr_pgrp = pstree["pgid"]
|
||||||
prpsinfo.pr_sid = pstree["sid"]
|
prpsinfo.pr_sid = pstree["sid"]
|
||||||
prpsinfo.pr_fname = core["tc"]["comm"]
|
|
||||||
prpsinfo.pr_psargs = self._gen_cmdline(pid)
|
prpsinfo.pr_psargs = self._gen_cmdline(pid)
|
||||||
|
if (sys.version_info > (3, 0)):
|
||||||
|
prpsinfo.pr_fname = core["tc"]["comm"].encode()
|
||||||
|
else:
|
||||||
|
prpsinfo.pr_fname = core["tc"]["comm"]
|
||||||
|
|
||||||
|
|
||||||
nhdr = elf.Elf64_Nhdr()
|
nhdr = elf.Elf64_Nhdr()
|
||||||
nhdr.n_namesz = 5
|
nhdr.n_namesz = 5
|
||||||
@ -317,7 +326,7 @@ class coredump_generator:
|
|||||||
|
|
||||||
note = elf_note()
|
note = elf_note()
|
||||||
note.data = prpsinfo
|
note.data = prpsinfo
|
||||||
note.owner = "CORE"
|
note.owner = b"CORE"
|
||||||
note.nhdr = nhdr
|
note.nhdr = nhdr
|
||||||
|
|
||||||
return note
|
return note
|
||||||
@ -375,7 +384,7 @@ class coredump_generator:
|
|||||||
|
|
||||||
note = elf_note()
|
note = elf_note()
|
||||||
note.data = prstatus
|
note.data = prstatus
|
||||||
note.owner = "CORE"
|
note.owner = b"CORE"
|
||||||
note.nhdr = nhdr
|
note.nhdr = nhdr
|
||||||
|
|
||||||
return note
|
return note
|
||||||
@ -411,7 +420,7 @@ class coredump_generator:
|
|||||||
|
|
||||||
note = elf_note()
|
note = elf_note()
|
||||||
note.data = fpregset
|
note.data = fpregset
|
||||||
note.owner = "CORE"
|
note.owner = b"CORE"
|
||||||
note.nhdr = nhdr
|
note.nhdr = nhdr
|
||||||
|
|
||||||
return note
|
return note
|
||||||
@ -452,7 +461,7 @@ class coredump_generator:
|
|||||||
|
|
||||||
note = elf_note()
|
note = elf_note()
|
||||||
note.data = data
|
note.data = data
|
||||||
note.owner = "LINUX"
|
note.owner = b"LINUX"
|
||||||
note.nhdr = nhdr
|
note.nhdr = nhdr
|
||||||
|
|
||||||
return note
|
return note
|
||||||
@ -472,7 +481,7 @@ class coredump_generator:
|
|||||||
|
|
||||||
note = elf_note()
|
note = elf_note()
|
||||||
note.data = siginfo
|
note.data = siginfo
|
||||||
note.owner = "CORE"
|
note.owner = b"CORE"
|
||||||
note.nhdr = nhdr
|
note.nhdr = nhdr
|
||||||
|
|
||||||
return note
|
return note
|
||||||
@ -482,7 +491,7 @@ class coredump_generator:
|
|||||||
Generate NT_AUXV note for thread tid of process pid.
|
Generate NT_AUXV note for thread tid of process pid.
|
||||||
"""
|
"""
|
||||||
mm = self.mms[pid]
|
mm = self.mms[pid]
|
||||||
num_auxv = len(mm["mm_saved_auxv"]) / 2
|
num_auxv = len(mm["mm_saved_auxv"]) // 2
|
||||||
|
|
||||||
class elf_auxv(ctypes.Structure):
|
class elf_auxv(ctypes.Structure):
|
||||||
_fields_ = [("auxv", elf.Elf64_auxv_t * num_auxv)]
|
_fields_ = [("auxv", elf.Elf64_auxv_t * num_auxv)]
|
||||||
@ -499,7 +508,7 @@ class coredump_generator:
|
|||||||
|
|
||||||
note = elf_note()
|
note = elf_note()
|
||||||
note.data = auxv
|
note.data = auxv
|
||||||
note.owner = "CORE"
|
note.owner = b"CORE"
|
||||||
note.nhdr = nhdr
|
note.nhdr = nhdr
|
||||||
|
|
||||||
return note
|
return note
|
||||||
@ -523,10 +532,10 @@ class coredump_generator:
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
shmid = vma["shmid"]
|
shmid = vma["shmid"]
|
||||||
off = vma["pgoff"] / PAGESIZE
|
off = vma["pgoff"] // PAGESIZE
|
||||||
|
|
||||||
files = self.reg_files
|
files = self.reg_files
|
||||||
fname = filter(lambda x: x["id"] == shmid, files)[0]["name"]
|
fname = next(filter(lambda x: x["id"] == shmid, files))["name"]
|
||||||
|
|
||||||
info = mmaped_file_info()
|
info = mmaped_file_info()
|
||||||
info.start = vma["start"]
|
info.start = vma["start"]
|
||||||
@ -569,6 +578,9 @@ class coredump_generator:
|
|||||||
setattr(data, "start" + str(i), info.start)
|
setattr(data, "start" + str(i), info.start)
|
||||||
setattr(data, "end" + str(i), info.end)
|
setattr(data, "end" + str(i), info.end)
|
||||||
setattr(data, "file_ofs" + str(i), info.file_ofs)
|
setattr(data, "file_ofs" + str(i), info.file_ofs)
|
||||||
|
if (sys.version_info > (3, 0)):
|
||||||
|
setattr(data, "name" + str(i), info.name.encode())
|
||||||
|
else:
|
||||||
setattr(data, "name" + str(i), info.name)
|
setattr(data, "name" + str(i), info.name)
|
||||||
|
|
||||||
nhdr = elf.Elf64_Nhdr()
|
nhdr = elf.Elf64_Nhdr()
|
||||||
@ -579,7 +591,7 @@ class coredump_generator:
|
|||||||
|
|
||||||
note = elf_note()
|
note = elf_note()
|
||||||
note.nhdr = nhdr
|
note.nhdr = nhdr
|
||||||
note.owner = "CORE"
|
note.owner = b"CORE"
|
||||||
note.data = data
|
note.data = data
|
||||||
|
|
||||||
return note
|
return note
|
||||||
@ -644,7 +656,7 @@ class coredump_generator:
|
|||||||
ppid = self.pstree[pid]["ppid"]
|
ppid = self.pstree[pid]["ppid"]
|
||||||
return self._get_page(ppid, page_no)
|
return self._get_page(ppid, page_no)
|
||||||
else:
|
else:
|
||||||
with open(self._imgs_dir + "/pages-%s.img" % pages_id) as f:
|
with open(self._imgs_dir + "/pages-%s.img" % pages_id, 'rb') as f:
|
||||||
f.seek(off * PAGESIZE)
|
f.seek(off * PAGESIZE)
|
||||||
return f.read(PAGESIZE)
|
return f.read(PAGESIZE)
|
||||||
|
|
||||||
@ -657,16 +669,16 @@ class coredump_generator:
|
|||||||
f = None
|
f = None
|
||||||
|
|
||||||
if size == 0:
|
if size == 0:
|
||||||
return ""
|
return b""
|
||||||
|
|
||||||
if vma["status"] & status["VMA_AREA_VVAR"]:
|
if vma["status"] & status["VMA_AREA_VVAR"]:
|
||||||
#FIXME this is what gdb does, as vvar vma
|
#FIXME this is what gdb does, as vvar vma
|
||||||
# is not readable from userspace?
|
# is not readable from userspace?
|
||||||
return "\0" * size
|
return b"\0" * size
|
||||||
elif vma["status"] & status["VMA_AREA_VSYSCALL"]:
|
elif vma["status"] & status["VMA_AREA_VSYSCALL"]:
|
||||||
#FIXME need to dump it with criu or read from
|
#FIXME need to dump it with criu or read from
|
||||||
# current process.
|
# current process.
|
||||||
return "\0" * size
|
return b"\0" * size
|
||||||
|
|
||||||
if vma["status"] & status["VMA_FILE_SHARED"] or \
|
if vma["status"] & status["VMA_FILE_SHARED"] or \
|
||||||
vma["status"] & status["VMA_FILE_PRIVATE"]:
|
vma["status"] & status["VMA_FILE_PRIVATE"]:
|
||||||
@ -675,9 +687,9 @@ class coredump_generator:
|
|||||||
off = vma["pgoff"]
|
off = vma["pgoff"]
|
||||||
|
|
||||||
files = self.reg_files
|
files = self.reg_files
|
||||||
fname = filter(lambda x: x["id"] == shmid, files)[0]["name"]
|
fname = next(filter(lambda x: x["id"] == shmid, files))["name"]
|
||||||
|
|
||||||
f = open(fname)
|
f = open(fname, 'rb')
|
||||||
f.seek(off)
|
f.seek(off)
|
||||||
|
|
||||||
start = vma["start"]
|
start = vma["start"]
|
||||||
@ -699,10 +711,10 @@ class coredump_generator:
|
|||||||
# a file, and changed ones -- from pages.img.
|
# a file, and changed ones -- from pages.img.
|
||||||
# Finally, if no page is found neither in pages.img nor
|
# Finally, if no page is found neither in pages.img nor
|
||||||
# in file, hole in inserted -- a page filled with zeroes.
|
# in file, hole in inserted -- a page filled with zeroes.
|
||||||
start_page = start / PAGESIZE
|
start_page = start // PAGESIZE
|
||||||
end_page = end / PAGESIZE
|
end_page = end // PAGESIZE
|
||||||
|
|
||||||
buf = ""
|
buf = b""
|
||||||
for page_no in range(start_page, end_page + 1):
|
for page_no in range(start_page, end_page + 1):
|
||||||
page = None
|
page = None
|
||||||
|
|
||||||
@ -720,7 +732,7 @@ class coredump_generator:
|
|||||||
|
|
||||||
if page is None:
|
if page is None:
|
||||||
# Hole
|
# Hole
|
||||||
page = PAGESIZE * "\0"
|
page = PAGESIZE * b"\0"
|
||||||
|
|
||||||
# If it is a start or end page, we need to read
|
# If it is a start or end page, we need to read
|
||||||
# only part of it.
|
# only part of it.
|
||||||
@ -762,7 +774,7 @@ class coredump_generator:
|
|||||||
chunk = self._gen_mem_chunk(pid, vma, size)
|
chunk = self._gen_mem_chunk(pid, vma, size)
|
||||||
|
|
||||||
# Replace all '\0's with spaces.
|
# Replace all '\0's with spaces.
|
||||||
return chunk.replace('\0', ' ')
|
return chunk.replace(b'\0', b' ')
|
||||||
|
|
||||||
def _get_vma_dump_size(self, vma):
|
def _get_vma_dump_size(self, vma):
|
||||||
"""
|
"""
|
||||||
|
@ -368,7 +368,7 @@ elf_fpregset_t = user_fpregs_struct
|
|||||||
# siginfo_t related constants.
|
# siginfo_t related constants.
|
||||||
|
|
||||||
_SI_MAX_SIZE = 128
|
_SI_MAX_SIZE = 128
|
||||||
_SI_PAD_SIZE = (_SI_MAX_SIZE / ctypes.sizeof(ctypes.c_int)) - 4
|
_SI_PAD_SIZE = (_SI_MAX_SIZE // ctypes.sizeof(ctypes.c_int)) - 4
|
||||||
|
|
||||||
|
|
||||||
# /* kill(). */
|
# /* kill(). */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user