Net::SMTPSを使い始めたところからの悪夢⇒DLLがロードされない問題の調査方法
苦しんだ3日間の奮闘メモ。
事の始まり
PerlのNet::SMTPSモジュールを使って、GmailのSMTPサーバー経由でメールを送ろうという試みを始めたところから悪夢は始まった。
プログラムのコアな部分は大まかに以下のような感じ。
sub send { my $self = shift; my ($args) = @_; my $from = $args->{from}; my $to = $args->{to}; my $header = $args->{header}; my $body = $args->{body}; my $config = MyConfig->new; $config->load(); my $smtp = $config->getSmtpAddress(); my $port = $config->getSmtpPort(); my $user = $config->getSmtpUser(); my $password = $config->getSmtpPassword(); my $mail = Net::SMTPS->new($smtp, Hello => $smtp, Port => $port, doSSL => 'starttls', Debug => 0 ); # $mail->starttls(); $mail->auth($user, $password); $mail->mail($from); $mail->to($to); $mail->data(); $mail->datasend(join("\r\n", $header, $body)); $mail->dataend(); $mail->quit(); }
とか。
こうすればいいのか、とか。
まぁいろいろとあったが、何とかCentOS 7のVM上でNet::SMTPSを使ってGmailのSMTPサーバー経由でメールを送れるようになった。
問題はここから。
悪夢の始まり
Windows環境に持ってきて、XAMPPに同梱されているPerl.exeで同じプログラムを実行すると、なぜか
Failed to open SMTPS connection: Bad file descriptor at・・
というエラーメッセージが出てメールが送れない。 printデバッグで、
require IO::Socket::SSL;
しているところで失敗しているっぽいことを突き止めたり、
SET PERL_DL_DEBUG=1
とすると、以下のようにデバッグログが出ることを知ったりする。
DynaLoader.pm loaded (. C:/xampp/perl/site/lib C:/xampp/perl/vendor/lib C:/xampp/perl/lib, C:\xampp\c\lib \xampp\c\x86_64-w64-mingw32\lib \xampp\c\lib\gcc\x86_64-w64-mingw32\8.3.0) DynaLoader::bootstrap for Net::SSLeay (auto/Net/SSLeay/SSLeay.xs.dll) DynaLoader::bootstrap for Digest::MD5 (auto/Digest/MD5/MD5.xs.dll) Failed to open SMTPS connection: Bad file descriptor at ・・・
そこで、DLLのロードをしているDynaLoader.pmにprintデバッグして、
MD5.xs.dll
ではなく、やはり SSLeay.xs.dll
のロードに失敗していることを確認。
SSLeayと言えば libeay32.dll
と ssleay32.dll
という頭もあったのだろう。
また、以下のサイトを見てしまったのも悪夢を助長させる要因となった。
(・・・2日後・・・)
ふと、「そもそも依存しているのはlibeay32.dll
と ssleay32.dll
じゃなかったりする?」と疑問を持ったところから急展開を見せる。
「DLL 依存性」などのキーワードで探すと、あるDLLが依存しているDLLの一覧を出力する方法を知る。
最初、コマンドプロンプトで
C:\Users\hhelibex>dumpbin /dependents C:\xampp\perl\vendor\lib\auto\Net\SSLeay\SSLeay.xs.dll 'dumpbin' は、内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチ ファイルとして認識されていません。
と言われて、あれ?と思って後者のサイトを見つけ、Visual Studio 2019をインストール&Windows OSの再起動をした。
サイトの記述に従い、Visual Studio 2019を起動し、[ツール]-[コマンドライン]-[開発者用 PowerShell]でPowerShellを起動し、コマンドを叩く。
すると、
********************************************************************** ** Visual Studio 2019 Developer PowerShell v16.11.26 ** Copyright (c) 2021 Microsoft Corporation ********************************************************************** PS C:\Users\hhelibex\source\repos> dumpbin /dependents C:\xampp\perl\vendor\lib\auto\Net\SSLeay\SSLeay.xs.dll Microsoft (R) COFF/PE Dumper Version 14.29.30148.0 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file C:\xampp\perl\vendor\lib\auto\Net\SSLeay\SSLeay.xs.dll File Type: DLL Image has the following dependencies: msvcrt.dll KERNEL32.dll libcrypto-1_1-x64__.dll libssl-1_1-x64__.dll perl532.dll Summary 1000 .CRT 2000 .bss 1000 .data 1000 .edata 8000 .idata 3000 .pdata D000 .rdata 1000 .reloc 5E000 .text 1000 .tls 4000 .xdata PS C:\Users\hhelibex\source\repos>
libcrypto-1_1-x64__.dll
と libssl-1_1-x64__.dll
!?初めて見たぞ。
とりあえずググる。そして、いろいろとダウンロードして名前を変更して(アンダースコア2つ「__」が入っていないので)、順番に試す。 ダメ。
途方に暮れながら、何気なくPC内を探す。 ・・ なんかある!?
C:\Users\hhelibex> dir C:\xampp\apache\bin ドライブ C のボリューム ラベルがありません。 ボリューム シリアル番号は 4006-07DE です C:\Users\hhelibex\xampp\apache\bin のディレクトリ 2023/05/23 20:33 <DIR> . 2023/05/23 20:33 <DIR> .. 2023/03/07 22:22 98,816 ab.exe 2023/03/07 22:22 110,592 abs.exe 2023/03/07 22:22 43,008 ApacheMonitor.exe 2023/03/07 22:22 19,456 apr_crypto_openssl-1.dll 2023/03/07 22:22 31,232 apr_dbd_odbc-1.dll 2023/03/07 22:22 14,848 apr_ldap-1.dll 2022/05/30 19:58 215,352 curl-ca-bundle.crt 2019/02/06 15:58 4,110,456 curl.exe 2023/03/07 22:25 9,192 dbmmanage.pl 2023/03/07 22:22 101,888 htcacheclean.exe 2023/03/07 22:22 124,416 htdbm.exe 2023/03/07 22:22 86,016 htdigest.exe 2023/03/07 22:22 118,784 htpasswd.exe 2023/03/07 22:24 30,720 httpd.exe 2023/03/07 22:22 65,536 httxt2dbm.exe 2023/05/23 20:33 <DIR> iconv 2023/03/15 03:30 30,422,016 icudt71.dll 2023/03/15 03:30 3,031,552 icuin71.dll 2023/03/15 03:30 60,928 icuio71.dll 2023/03/15 03:30 2,253,312 icuuc71.dll 2021/09/12 18:59 55,808 jansson.dll 2023/03/07 22:20 215,552 libapr-1.dll 2023/03/07 22:20 36,864 libapriconv-1.dll 2023/03/07 22:20 294,912 libaprutil-1.dll 2023/02/09 21:49 3,445,248 libcrypto-1_1-x64.dll ⇐☆☆☆ 2019/02/06 15:58 1,020,536 libcurl.dll 2023/03/07 22:21 459,776 libhttpd.dll 2023/03/15 03:30 209,920 libsasl.dll 2023/03/15 03:30 380,928 libssh2.dll 2023/02/09 21:50 689,664 libssl-1_1-x64.dll ⇐☆☆☆ 2022/11/02 01:03 1,373,696 libxml2.dll 2023/03/07 22:22 58,368 logresolve.exe 2019/04/05 23:28 184,320 lua52.dll 2023/03/07 22:16 156,160 nghttp2.dll 2023/02/09 21:51 550,912 openssl.exe 2021/08/23 23:32 400,896 pcre.dll 2023/01/12 18:44 564,224 pcre2-8.dll 2012/04/17 02:30 61,440 pv.exe 2023/03/07 22:22 78,848 rotatelogs.exe 2023/03/07 22:22 18,432 wintty.exe 2022/11/02 01:06 89,600 zlib1.dll 40 個のファイル 51,294,224 バイト 3 個のディレクトリ 415,936,548,864 バイトの空き領域 C:\Users\hhelibex>
ファイル名はちょっと違うけど、それっぽい! 早速PATHを通して実行してみる。。。やっぱりダメ。じゃあ、コピーして名前を変更して実行。 ・・・ 動いた!!!
じゃあ、PATHを通さずに、libcrypto-1_1-x64__.dll
と libssl-1_1-x64__.dll
だけコピーして・・ダメ。
まぁ、とりあえず動く方法が見つかって、ようやく一安心したところで、詳細を調べてみた。
先ほどのDLLの依存関係の続き。
PS C:\Users\hhelibex\source\repos> dumpbin /dependents C:\Users\hhelibex\SMTPServer\libcrypto-1_1-x64__.dll Microsoft (R) COFF/PE Dumper Version 14.29.30148.0 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file C:\Users\hhelibex\SMTPServer\libcrypto-1_1-x64__.dll File Type: DLL Image has the following dependencies: WS2_32.dll ADVAPI32.dll USER32.dll bcrypt.dll KERNEL32.dll VCRUNTIME140.dll api-ms-win-crt-stdio-l1-1-0.dll api-ms-win-crt-convert-l1-1-0.dll api-ms-win-crt-string-l1-1-0.dll api-ms-win-crt-time-l1-1-0.dll api-ms-win-crt-utility-l1-1-0.dll api-ms-win-crt-runtime-l1-1-0.dll api-ms-win-crt-filesystem-l1-1-0.dll api-ms-win-crt-heap-l1-1-0.dll api-ms-win-crt-environment-l1-1-0.dll Summary 1000 .00cfg 8000 .data 3000 .idata 1C000 .pdata CF000 .rdata 8000 .reloc 1000 .rsrc 252000 .text PS C:\Users\hhelibex\source\repos> dumpbin /dependents C:\Users\hhelibex\SMTPServer\libssl-1_1-x64__.dll Microsoft (R) COFF/PE Dumper Version 14.29.30148.0 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file C:\Users\hhelibex\SMTPServer\libssl-1_1-x64__.dll File Type: DLL Image has the following dependencies: libcrypto-1_1-x64.dll ⇐☆☆☆ KERNEL32.dll VCRUNTIME140.dll api-ms-win-crt-time-l1-1-0.dll api-ms-win-crt-string-l1-1-0.dll api-ms-win-crt-utility-l1-1-0.dll api-ms-win-crt-runtime-l1-1-0.dll api-ms-win-crt-convert-l1-1-0.dll api-ms-win-crt-stdio-l1-1-0.dll Summary 1000 .00cfg 5000 .data 6000 .idata 6000 .pdata 23000 .rdata 2000 .reloc 1000 .rsrc 74000 .text PS C:\Users\hhelibex\source\repos>
・・おまえか! libssl-1_1-x64__.dll
が libcrypto-1_1-x64.dll
に依存している。
だからlibcrypto-1_1-x64__.dll
と libssl-1_1-x64__.dll
だけあってもダメで、同じ内容でファイル名だけ違う libcrypto-1_1-x64.dll
がいないとダメなのか。
案の定、ファイルを3つ用意したら、PATHを通す必要もなく動いた。 あとは、これをWindowsサービス登録する形になるから、その場合にどうなるかだが、それはこれから調査。
反省
「SSLeay」と言えば「libeay32.dllとssleay32.dll」という思い込みから悪夢が始まり、3日間くらい浪費したので、思い込みは良くない。 でも、もう少しエラーメッセージを改善してほしい。依存しているけど見つからないライブラリをエラーメッセージに載せてくれればここまで悩まずに済んだんだけどな。