WindowsXPでPython2.7を使用しています。
pyodbcを使用して、今日まで完全に機能しているARデータベースからデータを取得する簡単なPythonスクリプトがスケジュールにあります。カーソルが特定の行に到達すると、セグメンテーション違反が発生します。結果を取得するのに問題のないC++の同様のコードがあるので、これはpyodbcの問題であると思います。いずれにせよ、このエラーを「キャッチ」したいと思います。サブプロセスモジュールを使用しようとしましたが、スクリプトがsegfaultにヒットすると、「python.exeで問題が発生したため、閉じる必要があります」でハングするため、機能しないようです。メッセージ。完了するまでに任意の時間枠を設定でき、そうでない場合は、プロセスを強制的に閉じることができると思いますが、それはちょっと足りないようです。
ここでも問題を報告しました-http://code.google.com/p/pyodbc/issues/detail ?id=278
@ paulsm4-以下の質問に答えました、ありがとう!
Q:Windows / XP(32ビット、私は想像します)、Python 2.7、およびBMCRemedyARを使用しています。正しい?
A:はい、WinXP32ビットおよびWinServer2008R264ビットでは失敗します。
Q:あなた(またはRemedy ARを購入した場合はクライアント)がBMCでサポートコールを開始できる可能性はありますか?
A:おそらくそうではありません...
Q:セグメンテーション違反の原因となっている列を特定できますか?セグメンテーション違反が発生したときの「何が違う」のですか?
A:この特定の行だけですが、以下の提案で問題を切り分けました。セグメンテーション違反が発生するまで、ループを使用して各フィールドをフェッチしました。
cursor.columns(table="mytable")
result = cursor.fetchall()
columns = [x[3] for x in result]
for x in columns:
print x
cursor.execute("""select "{0}"
from "mytable"
where id = 'abc123'""".format(x))
cursor.fetchall()
セグメンテーション違反の原因となる列を特定したら、それを除くすべての列に対してクエリを実行しましたが、問題なく機能することを確認しました。
列のデータ型はCHAR(1024)でした。C ++を使用してデータを取得したところ、その行の列に他の行の中で最も多くの文字が含まれていることに気付きました... 1023!PyODBCのCコードに、境界を越えて書き込まれているバッファがあるのではないかと考えています。
2)ODBCトレースを有効にします:http ://support.microsoft.com/kb/274551
3)結果(障害のログトレースを含む)をポストバックします。
OK、ODBCトレースの結果を使用してペーストビンを作成しました-http ://pastebin.com/6gt95rB8。罪のない人を保護するために、いくつかの文字列値をマスクしました。
データの切り捨てが原因である可能性があります。
これにより、問題を修正する方法について十分な情報が得られますか?C ODBC APIを直接使用すると正常に機能するため、PyODBC内のバグだと思います。
アップデート
そこで、デバッグ用にPyODBCをコンパイルしましたが、興味深いメッセージが表示されました-
Run-Time Check Failure #2 - Stack around the variable 'tempBuffer' was corrupted.
私は現在それを理解していませんが、コールスタックは次のとおりです-
pyodbc.pyd!GetDataString(Cursor * cur=0x00e47100, int iCol=0) Line 410 + 0xf bytes C++
pyodbc.pyd!GetData(Cursor * cur=0x00e47100, int iCol=0) Line 697 + 0xd bytes C++
pyodbc.pyd!Cursor_fetch(Cursor * cur=0x00e47100) Line 1032 + 0xd bytes C++
pyodbc.pyd!Cursor_fetchlist(Cursor * cur=0x00e47100, int max=-1) Line 1063 + 0x9 bytes C++
pyodbc.pyd!Cursor_fetchall(_object * self=0x00e47100, _object * args=0x00000000) Line 1142 + 0xb bytes C++
解決しました!
バッファに十分なスペースがあることを確認することで、問題は解決しました。
オンラインgetdata.cpp
330
char tempBuffer[1024];
に変更されました
char tempBuffer[1025];
サイトパッケージ内の古いpyodbc.pydファイルをコンパイルして置き換えれば、すべて問題ありません。
ご協力いただきありがとうございます!