如何调试Python中的C编译器错误?(malloc错误)

0 投票
2 回答
2375 浏览
提问于 2025-04-18 02:05

我正在用Python的Cherrypy做网页开发。

之前我有一个正常工作的网页,没有任何错误,但在我开始用Mako来处理前端代码并进行参数化后,出现了以下错误信息。

Python quit unexpectedly while using the libmysqlclient.18.dylib plug-in.

同时,控制台也显示了以下错误。

127.0.0.1 - - [09/Apr/2014:11:20:00] "GET /submit_data?idx=2 HTTP/1.1" 200 5990 "http://localhost:8080/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36"
python(375,0x103980000) malloc: *** error for object 0x7fb5a4061000: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6

看起来像是C编译器的错误,可能和MySQL有关,但我搞不清楚到底出了什么问题。

我该怎么办呢?我在猜测可能是我用MySQL的方式不对,我附上了我用来连接MySQL数据库的Python代码片段。

dbdict = {}
for name in params["dashboards"]:
    for chart in params["dashboards"][name]:
        dbdict[chart["dbname"]] = None

def connect(thread_index): 
    for name in dbdict:
        db = params["db"][name]
        dbdict[name] = MySQLdb.connect(db["host"], db["user"], db["password"], db["dbname"])

cherrypy.engine.subscribe('start_thread', connect)

class AjaxApp(object):
    @cherrypy.expose
    @cherrypy.tools.mako(filename="index.html", directories=MEDIA_DIR)
    def index(name=None):
        return {'size': len(params["dashboards"]["first"])}

    @cherrypy.expose 
    def submit_data(self, idx):
        idx = int(idx)
        chart = params["dashboards"]["first"][idx]
        # Sample page that displays the number of records in "table" 
        # Open a cursor, using the DB connection for the current thread 
        c = dbdict[chart["dbname"]].cursor() 
        print 'query being executed......'
        c.execute(chart["command"])
        print 'query being fetched......'
        res = c.fetchall()
        c.close()

        # construct a JSON object from query result
        jsres = []
        jsres.append(chart["selected"])
        q_result = []
        for x in res:
            tmp_arr = []
            for i in x:
                if type(i) is datetime.datetime:
                    tmp_arr.append(str(i))
                else:
                    tmp_arr.append(i)
            q_result.append(tmp_arr)
        jsres.append(q_result)

        return json.dumps(jsres)

在这里,我连接了所有使用的数据库,并把它们放在一个Python字典里。每当我运行查询命令时,我就查找对应的数据库对象,然后用它来执行查询。


现在我的connect函数是这样的

def connect(thread_index): 
    for name in dbdict:
        print name
        db = params["db"][name]
        cherrypy.thread_data.db = MySQLdb.connect(db["host"], db["user"], db["password"], db["dbname"])
        dbdict[name] = cherrypy.thread_data.db

我还是遇到了同样的错误。

2 个回答

1

python(375,0x103980000) malloc: * 对象 0x7fb5a4061000 的错误: 被释放的指针没有被分配 * 在 malloc_error_break 设置断点以进行调试

是的,这个错误是你提到的 C 程序错误,可能和 MYSQL 有关。这个错误的意思是,在你的程序中,有一个地址是没有通过 malloc/calloc/realloc 这些动态分配函数分配的。free() 函数是用来释放通过 malloc/calloc/realloc 分配的内存的。当你调用 free() 时,内存管理器会检查你传入的地址,如果检查不通过,就会抛出这样的错误信息并终止程序。

在你的程序中,可能是因为某种原因,错误的内存地址被传给了 free()。要从你的 PHP/MYSQL 代码中找出具体原因可能会有点困难。我建议你可以使用动态工具来调试你的程序,找出导致这个问题的原因。你也可以参考我之前的帖子。

https://stackoverflow.com/a/22658693/2724703

2

看起来你在多个线程之间共享了一个连接(在你的 connect() 函数中为每个数据库创建了一个连接)。这样可能会导致一些意想不到的同步问题,尤其是如果某个C语言库没有处理这种情况的话。你可以尝试将你的连接对象附加到 cherrypy.thread_data,具体方法可以参考这里

下面是我会写的代码(未经测试):

def connect(thread_index):
    cherrypy.thread_data.dbdict = dbdict = {}
    for name in params["dashboards"]:
        for chart in params["dashboards"][name]:
            dbdict[chart["dbname"]] = None
    for name in dbdict
        db = params["db"][name]
        dbdict[name] = MySQLdb.connect(db["host"], db["user"], db["password"], db["dbname"])

然后在 submit_data() 中:

@cherrypy.expose
def submit_data(self, idx):
    ...
    c = cherrypy.thread_data.dbdict[chart["dbname"]].cursor() 

撰写回答