进程已完成,退出代码为 139(被信号 11:SIGSEGV 中断)

问题描述 投票:0回答:1

我是Python新手,我需要帮助。 我用Ubuntu(64位)创建了一个虚拟机并安装了Pycharm,但是当我执行程序时出现错误(从互联网复制)。

当我在python3.6中运行时,它显示以下注释: picture1

当我在其他版本的python中运行时,它只显示以下注释: picture2

SDK来自这里

困扰我好几天了!感谢您的帮助!

代码:

import os
import ctypes
import base64
import json
import time
import logging
import psycopg2

from ctypes import *
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
from configparser import ConfigParser


class FinanceSdk:

    def __init__(self, path):
        self.so = ctypes.CDLL(path + 'libWeWorkFinanceSdk_C.so')

    def init_sdk(self, cropid, secret):
        so = self.so
        sdk = so.NewSdk()
        res = so.Init(sdk, cropid.encode('utf8'), secret.encode('utf8'))
        self.sdk = sdk
        return res

    def destory_sdk(self):
        self.so.DestroySdk(self.sdk)

    def get_chat_data(self, seq, limit, proxy, passwd, timeout):
        func = self.so.GetChatData
        func.restype = c_int
        func.argtypes = [c_int, c_long, c_int, c_char_p, c_char_p, c_int, c_int]
        res = None
        proxy = ('' if proxy == None else proxy).encode('utf8')
        passwd = ('' if passwd == None else passwd).encode('utf8')
        slice = self.new_slice()
        if func(self.sdk, seq, limit, proxy, passwd, timeout, slice) == 0:
            res = self.get_content_from_slice(slice)
        self.free_slice(slice)
        return res

    def decrypt_data(self, encrypt_key, private_key, encrypt_msg):
        func = self.so.DecryptData
        func.restype = c_int
        func.argtypes = [c_char_p, c_char_p, c_int]
        res = None
        key = self.rsa_decrypt(private_key, encrypt_key)
        slice = self.new_slice()
        if func(key, encrypt_msg.encode('utf8'), slice) == 0:
            res = self.get_content_from_slice(slice)
        self.free_slice(slice)
        return res

    def get_media_data(self, index_buf, sdk_field, proxy, passwd, timeout,
                       media_data):
        func = self.so.GetMediaData
        func.restype = c_int
        func.argtypes = [c_int, c_char_p, c_char_p, c_char_p, c_char_p,
                         c_int, c_int]
        index_buf = ('' if index_buf == None else index_buf).encode('utf8')
        sdk_field = ('' if sdk_field == None else sdk_field).encode('utf8')
        proxy = ('' if proxy == None else proxy).encode('utf8')
        passwd = ('' if passwd == None else passwd).encode('utf8')
        return func(self.sdk, index_buf, sdk_field, proxy, passwd,
                    timeout, media_data)

    def new_slice(self):
        func = self.so.NewSlice
        func.restype = c_int
        return func()

    def get_content_from_slice(self, slice):
        func = self.so.GetContentFromSlice
        func.restype = c_char_p
        func.argtypes = [c_int]
        return func(slice)

    def free_slice(self, slice):
        func = self.so.FreeSlice
        func.restype = c_void_p
        func.argtypes = [c_int]
        func(slice)

    def new_media_data(self):
        func = self.so.NewMediaData
        func.restype = c_int
        return func()

    def get_data(self, media_data):
        func = self.so.GetData
        func.restype = c_int
        func.argtypes = [c_int]
        ptr = func(media_data)
        size = self.get_data_len(media_data)
        return string_at(ptr, size)

    def get_data_len(self, media_data):
        func = self.so.GetDataLen
        func.restype = c_int
        func.argtypes = [c_int]
        return func(media_data)

    def get_out_index_buf(self, media_data):
        func = self.so.GetOutIndexBuf
        func.restype = c_char_p
        func.argtypes = [c_int]
        return func(media_data)

    def is_media_data_finish(self, media_data):
        func = self.so.IsMediaDataFinish
        func.argtypes = [c_int]
        return func(media_data)
        func.restype = c_int

    def free_media_data(self, media_data):
        func = self.so.FreeMediaData
        func.restype = c_void_p
        func.argtypes = [c_int]
        func(media_data)

    def rsa_decrypt(self, private_key, text):
        pri_key = RSA.import_key(private_key)
        cipher = PKCS1_v1_5.new(pri_key)
        return cipher.decrypt(base64.b64decode(text), None)


class Backuper:

    def __init__(self):
        self.config = self._read_config()
        db = self.config['database']
        self.conn = psycopg2.connect(
                host=db['host'],
                port=db['port'],
                database=db['database'],
                user=db['user'],
                password=db['password'])
        self.logger = logging.getLogger(__name__)
        self.media_types = ['image', 'video', 'voice', 'emotion', 'file']
        self.exts = {'image': 'jpg', 'video': 'mp4', 'voice': 'amr'}

    def backup(self):
        seq = self._get_sequance()
        sdk = FinanceSdk(self.config['backup']['root_path'])
        weixin = self.config['weixin']
        if sdk.init_sdk(weixin['cropid'], weixin['secret']) != 0:
            self.logger.error('SDK init error')
            return
        # 获取聊天内容
        res = sdk.get_chat_data(seq, weixin['limit'],
                                weixin['proxy_url'], weixin['proxy_password'],
                                weixin['timeout'])
        if res is None:
            self.logger.error('SDK getCharData error')
            return

        chat_datas = json.loads(res)
        data_list = chat_datas['chatdata']
        for item in data_list:
            key = item['encrypt_random_key']
            msg = item['encrypt_chat_msg']
            res = sdk.decrypt_data(key, weixin['private_key'], msg)
            if res is None:
                self.logger.error('SDK decryptData error: ' + str(item['seq']))
            else:
                data = json.loads(res)
                print(data)
                self.logger.info('SDK decryptData: ' +
                        str(item['seq']) + '-' + data['msgtype'])
                self.save_message(data, item['seq'])
                file_path = ''
                if data['msgtype'] in self.media_types:
                    file_path = self.save_media_data(sdk, data)
                    print(file_path)
                self.save_record(data, file_path)


        sdk.destory_sdk()
        try:
            self.conn.commit()
        except Exception as e:
            self.conn.rollback()
            self.logger.error('db error: ' + str(e))
        self.conn.close()

    def save_message(self, data, seq):
        backup = self.config['backup']
        path = backup['path']
        month_path = self._format_timestamp(data['msgtime'], '%Y%m')
        path = path + month_path + '/'
        if not os.path.exists(path):
            os.makedirs(path)
        filename = self._format_timestamp(data['msgtime'], '%Y%m%d') + '.txt'
        file = open(path + filename, 'a')
        data['seq'] = seq
        file.write(json.dumps(data) + '\r\n')
        file.close()

    def save_media_data(self, sdk, data):
        weixin = self.config['weixin']
        msgtype = data['msgtype']
        raw_data = data[msgtype]
        ext = ''
        if 'fileext' in raw_data:
            ext = raw_data['fileext']
        elif msgtype in self.exts:
            ext = self.exts[msgtype]
        elif msgtype == 'emotion':
            ext = ('gif' if raw_data['type'] == 1 else 'png')
        ext = ('' if len(ext) == 0 else ('.' + ext))
        path = self.config['backup']['path']
        month_path = self._format_timestamp(data['msgtime'], '%Y%m')
        path = path + month_path + '/media/'
        if not os.path.exists(path):
            os.makedirs(path)
        filename = msgtype + '_' + data['msgid'] + ext
        if os.path.exists(path + filename):
            os.remove(path + filename)

        file = open(path + filename, 'ab')
        index_buf = ''
        while True:
            media_data = sdk.new_media_data()
            res = sdk.get_media_data(index_buf,
                                     raw_data['sdkfileid'],
                                     weixin['proxy_url'],
                                     weixin['proxy_password'],
                                     weixin['timeout'],
                                     media_data)
            if res != 0:
                sdk.free_media_data(media_data)
                file.close()
                if os.path.exists(path + filename):
                    os.remove(path + filename)
                self.logger.error('SDK getMediaData error: ' + json.dumps(data))
                break
            content = sdk.get_data(media_data)
            file.write(content)
            if sdk.is_media_data_finish(media_data) == 1:
                sdk.free_media_data(media_data)
                file.close()
                break
            else:
                index_buf = str(sdk.get_out_index_buf(media_data),
                                encoding = 'utf8')
                sdk.free_media_data(media_data)
        if os.path.exists(path + filename):
            self.logger.info('media file saved: ' + path + filename)
        return (path + filename)

    def save_record(self, data, file_path):
        cursor = self.conn.cursor()
        backup_path_len = len(self.config['backup']['path'])
        if len(file_path) > backup_path_len:
            file_path = file_path[backup_path_len:]
        try:
            sql = "delete from messages where id='%s'" % (data['msgid'])
            cursor.execute(sql)
            record = {}
            record['id'] = data['msgid']
            record['sequance'] = str(data['seq'])
            record['action'] = data['action']
            record['from_user'] = data['from']
            record['to_user_list'] = ','.join(data['tolist'])
            record['room_id'] = data['roomid'] if 'roomid' in data else ''
            record['message_time'] = self._format_time(data['msgtime'])
            record['message_type'] = data['msgtype']
            record['content'] = ''
            record['raw_data'] = ''
            record['file_path'] = file_path
            record['created_at'] = self._format_time(int(time.time() * 1000))
            if data['msgtype'] in data:
                raw_data = data[data['msgtype']]
                record['raw_data'] = json.dumps(raw_data)
                if data['msgtype'] == 'text':
                    record['content'] = raw_data['content']
            sql = (
                    "insert into messages (id, sequance, action, from_user, "
                    "to_user_list, room_id, message_time, message_type, "
                    "content, raw_data, file_path, created_at) values ("
                    "'%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', "
                    "'%s', '%s', '%s', '%s')"
            )
            sql = sql % (record['id'], record['sequance'],
                    record['action'], record['from_user'],
                    record['to_user_list'], record['room_id'],
                    record['message_time'], record['message_type'],
                    record['content'], record['raw_data'],
                    record['file_path'], record['created_at'])
            cursor.execute(sql)
        except:
            pass
        finally:
            cursor.close()

    def _read_config(self):
        path = os.getcwd()
        if not path.endswith('/'):
            path = path + '/'
        config_file = path + 'config.cfg'
        cp = ConfigParser()
        cp.read(config_file)
        config = {}
        for section in cp.sections():
            config[section] = {}
            for item in cp.items(section):
                config[section][item[0]] = item[1]
        private_key_file = path + config['weixin']['private_key']
        file = open(private_key_file)
        config['weixin']['private_key'] = file.read()
        file.close()
        backup_path = config['backup']['path']
        if not backup_path.startswith('/'):
            backup_path = path + backup_path
        if not backup_path.endswith('/'):
            backup_path = backup_path + '/'
        config['backup']['root_path'] = path
        config['backup']['path'] = backup_path
        config['database']['port'] = int(config['database']['port'])
        config['weixin']['limit'] = int(config['weixin']['limit'])
        config['weixin']['timeout'] = int(config['weixin']['timeout'])
        config['backup']['interval'] = int(config['backup']['interval'])
        return config

    def _get_sequance(self):
        seq = 0
        cursor = self.conn.cursor()
        try:
            sql = 'select max(sequance) from messages'
            cursor.execute(sql)
            rs = cursor.fetchall()
            if len(rs) > 0:
                seq = rs[0][0]
                seq = 0 if seq == None else seq
        except:
            pass
        finally:
            cursor.close()
        return seq

    def _format_timestamp(self, timestamp, format):
        time_array = time.localtime(timestamp / 1000)
        return time.strftime(format, time_array)

    def _format_time(self, timestamp):
        time_array = time.localtime(timestamp / 1000)
        milliseconds = str(timestamp % 1000)
        return time.strftime('%Y-%m-%d %H:%M:%S.', time_array) + milliseconds


if __name__ == '__main__':
    logging.basicConfig(
            filename='out.log', filemode='a', level=logging.INFO,
            format='%(asctime)s [%(levelname)s] %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S')
    backuper = Backuper()
    backuper.backup()
    interval = backuper.config['backup']['interval']
    start_time = time.time()
    while True:
        current_time = time.time()
        if current_time - start_time < interval:
            print(1)
            time.sleep(1)
        else:
            backuper = Backuper()
            backuper.backup()
            start_time = time.time()

我尝试了不同版本的python,但没有帮助。

python python-3.x segmentation-fault
1个回答
0
投票

SDK来自这里

这是一个错误,可能是您下载的 SDK 中的错误。您应该联系 SDK 开发人员,因为他们是唯一能够对此采取行动的人。

© www.soinside.com 2019 - 2024. All rights reserved.