LoginSignup
3
0

More than 1 year has passed since last update.

macでpythonのDb2ライブラリ ibm_dbをimportすると発生するエラーへの対応策(Symbol not found: ___cxa_throw_bad_array_new_length )

Last updated at Posted at 2023-03-30

macOSをアップグレードして、pythonもupgradeしたら(何きっかけか不明なんですが)今まで動いていたpythonのDb2ライブラリibm_dbがimportでエラーになるようになってしまいました。
メモとして、ここに解決策を書いておきます。

以下のversionでの動作です

  • macOS: Ventura 13.2.1
  • python: Python 3.11.2
  • VS Code: 1.76.2 (Universal)
  • gcc 8 (解決策として導入)

問題 import ibm_dbでエラー

エラーは具体的には以下のような感じです:

>>> import ibm_db
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: dlopen(/Users/xxxx/python_venv/db2/.db2_venv/lib/python3.11/site-packages/ibm_db.cpython-311-darwin.so, 0x0002): Symbol not found: ___cxa_throw_bad_array_new_length
  Referenced from: <855AE640-1BCF-3A61-A65E-58F5490BFF43> /Users/xxxx/python_venv/db2/.db2_venv/lib/python3.11/site-packages/clidriver/lib/libdb2.dylib
  Expected in:     <31679759-38DC-357A-95C2-542EA70F295F> /usr/lib/libstdc++.6.dylib

Symbol not found: ___cxa_throw_bad_array_new_lengthというエラーが出てます。

解決策

調べたところlibstdc++.6.dyliblibgcc_s.1.1.dylibがどこかの(!)Mac OSのバージョンのからなくなったそうで、gcc version 8以降を導入して入手しておかなくてはならないそうです。
このあたりに書いてありました: https://github.com/ibmdb/python-ibmdb/issues/540

ということでgccを導入。brewで導入しました。その時デフォで入るversion12.2でやってみたところ、ところどころうまく動きませんでしたので、v8を入れておくのが無難です。
コマンドは以下:

brew install gcc@8

で、この導入したgccのライブラリーのパスをDYLD_LIBRARY_PATHに設定後、pythonを実行する必要があります。

export DYLD_LIBRARY_PATH=/usr/local/lib/gcc/8:$DYLD_LIBRARY_PATH

毎回コマンドを打つのもの面倒なので、~/.zshrcに上記の一行入れてしまえば、次回からターミナルを開けば設定済みになります。

追加解決策 VSCodeのJupyter Notebookの場合

実際のところVSCodeのJupyter Notebookで使いたかったのですが、上記の設定をしたターミナルから直でcode .で 立ち上げても、DYLD_LIBRARY_PATHがセットされてないという問題がありました。 ibm_dbをimportはできるのですが、DYLD_LIBRARY_PATHがセットされてないとDb接続時にカーネルがクラッシュします。

参考:

どうやらターミナルで設定された環境変数はVSCode上のJupyter Notebookで引き継がないそうで(なんで??)。

ワークスペースのフォルダー内に.envファイルを作成してそこに設定すればよいとのことで、そのようにしたのですが、他の環境変数は反映されるのになぜかDYLD_LIBRARY_PATHという環境変数だけ反映されず。。。。
このあたりにいろいろ書いてありました: https://github.com/golang/vscode-go/issues/468#issue-672591555
この結論が代わりにLD_LIBRARY_PATHを使えになってますが、この環境変数では動きませんでした。

いろいろやりましたが、どうしてもDYLD_LIBRARY_PATHの設定ができず、結局VSCode上でJupyter Notebookを使いibm_dbを使いたい場合は、
Jupyter Notebookを解決策の環境で起動させ、そこにVSCodeから接続する
とういう方法になると思います。

簡単にその方法です。

1. 解決策の環境のターミナルからJupyter Notebookの起動

VSCodeから繋ぐので、ちょっとしたオプションを入れます。
オプションipの値は、だと全てから接続を許可してしまうので、制限したい場合は接続元のipアドレスを入れてください。

jupyter notebook --ip='*' --no-browser

起動させると以下のようなメッセージが表示されます

[I 12:44:43.822 NotebookApp] ローカルディレクトリからノートブックをサーブ: /Users/nishito/python_venv/db2
[I 12:44:43.822 NotebookApp] Jupyter Notebook 6.5.3 is running at:
[I 12:44:43.822 NotebookApp] http://xxxxxxxxxxxxxxxxxxxx.local:8888/?token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[I 12:44:43.822 NotebookApp]  or http://127.0.0.1:8888/?token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[I 12:44:43.822 NotebookApp] サーバを停止し全てのカーネルをシャットダウンするには Control-C を使って下さい(確認をスキップするには2回)。

表示された
http://xxxxxxxxxxxxxxxxxxxx.local:8888/?token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
をどこかにコピーしておきます(xxxxxの部分は環境で異なります)

2. VSCodeでカーネルを起動した Jupyter Notebookを設定

⌃⌥⌘Nで「新しいファイル」から「Jupyter Notebook」を選びます。または既存Jupyter Notebookのファイル(*.ipynb)を開きます。
image.png

右上のカーネルの選択をクリックします。
image.png

「既存のJupyterサーバー」を選択します。
image.png

1でコピーした実行中のJupyterサーバーのURLを入力し、Enterを押下します。
image.png

表示されたカーネルを選択します。
image.png

右上にカーネルが正しく表示されているのを確認します。
image.png

これでibm_dbがVSCodeのJupyter Notebookで無事importできるようになりました!
(ちょっと面倒)

3. Tips

Jupyter Notebookを停止したい時は、動作しているターミナルで Control-C 入力します(確認をスキップするには2回入力)。

尚、再度新規にJupyter Notebookを起動させた場合、tokenが変わりますので、再度カーネルの選択でJupyterサーバーのURLを入力し設定する必要があります。その際以前使用していたものは、ゴミ箱アイコンを使用して削除するようにしてください。
image.png

以上です。

3
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0