如何调试Python中的C编译器错误?(malloc错误)
我正在用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 个回答
python(375,0x103980000) malloc: * 对象 0x7fb5a4061000 的错误: 被释放的指针没有被分配 * 在 malloc_error_break 设置断点以进行调试
是的,这个错误是你提到的 C 程序错误,可能和 MYSQL 有关。这个错误的意思是,在你的程序中,有一个地址是没有通过 malloc/calloc/realloc 这些动态分配函数分配的。free() 函数是用来释放通过 malloc/calloc/realloc 分配的内存的。当你调用 free() 时,内存管理器会检查你传入的地址,如果检查不通过,就会抛出这样的错误信息并终止程序。
在你的程序中,可能是因为某种原因,错误的内存地址被传给了 free()。要从你的 PHP/MYSQL 代码中找出具体原因可能会有点困难。我建议你可以使用动态工具来调试你的程序,找出导致这个问题的原因。你也可以参考我之前的帖子。
看起来你在多个线程之间共享了一个连接(在你的 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()