Wget segfault - どのウェブサイトが問題を引き起こしているのかどうかはどうすればわかりますか?

Wget segfault - どのウェブサイトが問題を引き起こしているのかどうかはどうすればわかりますか?

ウェブサイトをローカルにミラーリングしようとしています。しかし、ダウンロードプロセスの一貫した時点で、私のターゲットサイトとは異なるドメインにある分割エラーが発生しました(おそらくそのためです--page-requisites)。

2018-04-09 04:58:32 (346 KB/s) - './not-website.com/2017/06/28/xyz/index.html' saved [145810]

29247 Segmentation Fault      (core dumped) wget --directory-prefix="${DL_ROOT}" --recursive --page-requisites --span-hosts --tries="${TRIES_NUM}" --timeout="${TIMEOUT_NUM}" --reject="*.tar" --convert-links --adjust-extension --continue --no-check-certificate "http://website.com/"

したがって、wgetは特定のWebサイトをダウンロードしようとしましたが、失敗して分割エラーが発生したと思います。

しかし、エラーメッセージはwgetが失敗したアドレスを知らせていないようです。最後に成功したダウンロードのみをお知らせします。このsegfaultによってwgetが失敗する場所/理由をどのように知ることができますか?

coreエラーは55Mファイルを参照しているようですが、プレーン(core dumped)テキストではありません。私に必要な情報が含まれていますか?この情報をどのように抽出しますか?

ディストリビューション(Solaris、Debian、Raspbian)でこれをテストし、このsegfaultは一貫しており、常に同じアドレス(上記のnot-website.com/...エラーメッセージ)に従います。

私は次のコマンドを使用しています:

$ wget \
    --directory-prefix="${DL_ROOT}" \
    --recursive \
    --page-requisites \
    --span-hosts \
    --tries="${TRIES_NUM}" \
    --timeout="${TIMEOUT_NUM}" \
    --reject="*.tar" \
    --convert-links \
    --adjust-extension \
    --continue \
    --no-check-certificate \
  "http://website.com/"

追加情報

これは多くのメディアを備えた大規模なウェブサイトです。障害当時ダウンロードされたディレクトリのサイズは約252M程度であった。

テスト対象:

GNU Wget 1.18 built on solaris2.10.

-cares +digest -gpgme +https +ipv6 -iri +large-file -metalink -nls 
+ntlm +opie -psl +ssl/openssl 

そして

GNU Wget 1.18 built on linux-gnu.

-cares +digest -gpgme +https +ipv6 +iri +large-file -metalink +nls 
+ntlm +opie +psl +ssl/gnutls

そして

GNU Wget 1.16 built on linux-gnueabihf.

+digest +https +ipv6 +iri +large-file +nls +ntlm +opie +psl +ssl/gnutls

答え1

スプリットエラーは、プログラム(この場合はwget)が誤ったメモリアドレスにアクセスしようとしたため、カーネルによって終了したことを意味します。これは通常、プログラミングのバグが原因であるため、特定のWebサイトまたはWebページによって発生する可能性が最も高いですが(複数のプラットフォームの同じ時点でかなり一貫して再現できると考えられています)、まだ公開される可能性がある問題です。 wget自体のバグ。

wgetで分割エラーが発生した場所を見つけるには、プログラムgdb(GNUデバッガ)を使用してwgetがクラッシュしたときにスタックトレースを取得できます。これはファイルがあるため可能ですcore。 (コアダンプは、分割エラーなどの誤動作によって実行中のプログラムが終了したときに撮影された画像のコピーです。)

これを行うには、次のコマンドを使用します。

$ gdb wget core

wgetこれにより(パスで)バイナリでデバッガが実行され、coreファイル(現在のディレクトリにある)が実行中のプログラムのイメージに復元されます。

gdbその後、プログラムに関する情報を印刷してプロンプトを表示します。

$ gdb wget core
GNU gdb (GDB) 7.9
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
...
Core was generated by `wget --directory-prefix=... --recursive --page-requisites --span-hosts --tries=... --timeout=... --reject=*.tar --convert-links --adjust-extension --continue --no-check-certificate http://website.com/'.
Program terminated with signal SIGSEGV, Segmentation Fault.
(gdb) _

この時点で、このコマンドbt(「backtrace」の略語)を使用して、プログラムがクラッシュしたときに実行されていた内容を表示できます。これは通常、エラーの検索を開始するのに最適な場所です。

たとえば、次の内容が表示されることがあります。

(gdb) bt
#0  0x00007f5371206363 in __select_nocancel () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x0000559e5acbf21c in select_fd ()
#2  0x0000559e5acf0bde in wgnutls_poll ()
#3  0x0000559e5acbf3a2 in poll_internal ()
#4  0x0000559e5acbf6ed in fd_peek ()
#5  0x0000559e5ace423d in fd_read_hunk ()
#6  0x0000559e5acd5ef9 in gethttp ()
#7  0x0000559e5acd9b26 in http_loop ()
#8  0x0000559e5ace53c8 in retrieve_url ()
#9  0x0000559e5ace273b in retrieve_tree ()
#10 0x0000559e5acbe67d in main ()

その後、(「quit」)コマンドをgdb使用して終了できます。q

(gdb) q

「デバッグシンボル」がインストールされていると役に立つことがよくあります。これは、デバッグバイナリ用にコンパイラによって生成された情報であり、通常システムにインストールされているバイナリから削除され、サイズが小さくなります。この情報は、バイナリをデバッグするときに見つけることができる他の場所(通常は下)に保存できます/usr/lib/debuggdb

この情報を使用すると、通常、すべての内部関数の名前などの追加情報がトレースバックに追加されます。

Debian では、以下を使用して wget のデバッグ情報をインストールできます。

$ sudo apt-get install wget-dbgsym

glibc用のデバッグシンボルをインストールすることもできます。

$ sudo apt-get install libc6-amd64-dbgsym

wgetの競合の原因を調べる前に、ダウンロードできる最新バージョンのwgetを試してみることをお勧めします。 1.9.4のようです。ここ。これはソースパッケージなので、システムで動作するにはソースからビルドする必要があります。

これは、分割エラーが通常バグによって発生し、バグがwgetで修正された可能性が高く、最新バージョンに修正が存在するためです。

最新バージョンで同じ問題が発生した場合は、コアファイルをインポートしてgdbを使用してトレースを取得し、wget管理者にバグを報告して修正する機会を得てください。

最新のwget 1.9.4で修正されているが使用しているDebianバージョンに存在する場合は、そのパッチをwgetバージョンにバックポートできるようにDebianに問題を報告することを検討してください。

という新しいプロジェクトもあります。wget2、彼らはwgetを新しいコードベースに置き換えようとしているようです。それがうまくいくかどうかを確認したいかもしれません... Debianが最近「wget2」という名前でリリースしたようです。

この指示が役に立つことを願っています!

関連情報