웹사이트를 로컬로 미러링하려고 합니다. 그러나 다운로드 프로세스의 일관된 지점에서 내 대상 사이트와 다른 도메인에 있는 분할 오류가 발생했습니다(아마도 그 때문일 것입니다 --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이 특정 웹 사이트를 다운로드하려고 시도했지만 실패하여 분할 오류가 발생했다고 생각합니다.
그러나 오류 메시지는 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)이 잘못된 메모리 주소에 액세스하려고 시도하여 커널에 의해 종료되었음을 의미합니다. 이는 일반적으로 프로그래밍 버그로 인해 발생하므로 특정 웹 사이트나 웹 페이지에 의해 발생할 가능성이 가장 높지만(여러 플랫폼의 동일한 지점에서 꽤 일관되게 재현할 수 있는 것으로 생각됨) 여전히 노출될 수 있는 문제입니다. 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/debug
.gdb
이 정보를 사용하면 일반적으로 모든 내부 함수의 이름과 같은 추가 정보가 트레이스백에 추가됩니다.
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을 새로운 코드 베이스로 대체하려고 하는 것 같습니다. 작동하는지 확인하고 싶을 수도 있습니다... 데비안이 최근 "wget2"라는 이름으로 출시한 것 같습니다.
이 지침이 도움이 되기를 바랍니다!