이미 알고 있듯이 Common Gateway 인터페이스 인 CGI는 표준 입력 및 환경 변수를 통해 HTTP 요청 데이터를 프로그램에 전달하고 프로그램의 표준 출력을 HTTP 응답으로 반환하여 웹 서버가 프로그램을 실행할 수있는 표준 프로토콜입니다. FASTCGI 또는 SCGI를 사용하지 않는 한, 실행 프로그램은 각 요청에 대해 웹 서버에 의해 별도의 프로세스로 시작되고 끝에 찢어졌습니다.
GNU 디버거 인 GDB는 일반적으로 C 및 C ++ 프로그램을 디버그하는 데 사용되며 실행되는 프로세스에 연결을 지원합니다. CGI 프로세스가 수명이 짧으므로 프로세스가 여전히 실행중인 동안 디버거를 부착하기에 충분한 시간이 있도록 출구가 지연되어야합니다. 캐주얼 디버깅의 경우 가장 쉬운 옵션은 브레이크 포인트 위치의 끝없는 루프에서 sleep() 사용하고 프로그램에 연결되면 디버거로 루프를 종료하는 것입니다. 내가 여기서 다루지 않는 더 복잡한 옵션이 있습니다.
다음 예는 Ubuntu Linux와 Apache를 가정합니다.
먼저 CGI 모듈을 설치하고 활성화합니다.
sudo a2enmod cgi
그런 다음 CGI 지원 가상 호스트를 구성하십시오.
<VirtualHost *:80>
ServerName cgi-test.example.com
DocumentRoot /var/www/cgi-test/htdocs
CustomLog /var/log/apache2/cgi-test.access.log combined
ErrorLog /var/log/apache2/cgi-test.error.log
TimeOut 600
ScriptAlias /cgi-bin/ /var/www/cgi-test/cgi-bin/
<Directory "/var/www/cgi-test/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
TimeOut 매개 변수에 유의하십시오 - 기본 1 분 대신 디버깅에 10 분을 보유합니다. 타임 아웃에 도달 한 후 Apache는 CGI 프로세스를 죽이고 504 게이트웨이 타임 아웃 응답을 반환합니다.
마지막으로 Apache를 다시 시작하십시오.
sudo service apache2 restart
빌드 도구 설치 :
sudo apt-get install build-essentials cmake cgdb
복제 및 컴파일 응용 프로그램 :
git clone https://github.com/mrts/debugging-cgi-applications-with-gdb.git
cd debugging-cgi-applications-with-gdb
cmake .
make
응용 프로그램을 cgi-bin 디렉토리로 복사하십시오.
cp cgi-debugging-example /var/www/cgi-test/cgi-bin
브라우저에서 애플리케이션을 실행하는 URL을 엽니 다.
http://cgi-test.example.com/cgi-bin/cgi-debugging-example
응용 프로그램이 끝없는 루프로 들어가고 이제 GDB에 부착 할 수 있으므로 브라우저에는로드 아이콘이 표시됩니다.
일반 GDB 대신 CGDB를 사용하는 것이 좋습니다. CGDB는 GDB의 저주 전면으로, 실행 된 소스를 보여주는 분할 화면이있는 친숙한 GDB 텍스트 인터페이스를 제공합니다.
pgrep 에서 CGI 프로세스 ID를 찾을 수 있습니다.
pgrep -l cgi-debugging
프로세스에 CGDB를 첨부하십시오 (디버거가 첨부 될 때 프로세스가 일시 중지됩니다).
sudo cgdb cgi-debugging-example $(pgrep cgi-debugging)
다음으로 응용 프로그램의 "브레이크 포인트"에 도달하려면 무한 루프 및 wait_for_gdb_to_attach() 함수를 종료해야합니다. 여기서 속임수는 wait_for_gdb_to_attach() 에 도달 할 때까지 sleep() 벗어나서 디버거로 변수 is_waiting 의 값을 설정하여 while (is_waiting) 이 종료되도록하는 것입니다.
(gdb) finish
Run till exit from 0x8a0920 __nanosleep_nocancel () at syscall-template.S:81
0x8a07d4 in __sleep (seconds=0) at sleep.c:137
(gdb) finish
Run till exit from 0x8a07d4 in __sleep (seconds=0) at sleep.c:137
wait_for_gdb_to_attach () at cgi-debugging-example.c:6
Value returned is $1 = 0
(gdb) set is_waiting = 0 # <- to exit while
(gdb) finish
Run till exit from wait_for_gdb_to_attach () cgi-debugging-example.c:6
main () at cgi-debugging-example.c:13
return 으로 반환을 강제로 강제로 강요 할 수도 있지만 응용 프로그램 상태를 엉망으로 만들고 충돌이 발생할 수 있습니다. 또는 finish next 기능을 중단하는 데 사용될 수 있습니다.
wait_for_gdb_to_attach() 가 없으면 프로그램을 계속 디버깅하거나 완료하도록 할 수 있습니다.
(gdb) next
(gdb) continue
Continuing.
[Inferior 1 (process 1005) exited normally]
(gdb) quit
브라우저는 이제 프로그램 출력을 보여 주어야합니다 - 안녕하세요!