nginx學習- 開篇,搭建除錯環境
今天開始nginx的學習,Mark一下。爭取能在一個月入門個皮毛,對於nginx的打算,主要是學習其各種應用場景和配置,下好原始碼只是為了配合理解。
搭建除錯環境
首先還是搭個除錯環境,下好了nginx程式碼以後,檢視目錄。
localhost:nginx-master jjchen$ tree -L 1 . ├── Makefile ├── auto ├── conf ├── contrib ├── docs ├── misc ├── objs └── src
直接編譯
bash auto/configure make
程式就編譯好了,可執行程式生成在objs/nginx。
程式碼在src中,我們用ide將程式碼匯入,我這裡是xcode。此處直接匯入程式碼,沒有處理編譯錯誤,不能直接debug運行了,我們直接用附加程式的方式來除錯。注意先附加到程序,後啟動程式。
進入objs目錄,啟動nginx程式,這裡用了root許可權,不然一些日誌檔案建立不了。
sudo ./nginx -c ../conf/ngin.conf
開始跟蹤程式碼。--- 發現了大問題,debug的堆疊資訊好像不準,而且IDE內函式不能跳轉。。
看來不能偷懶了,還是回到開頭,修改配置,修改程式碼讓IDE能直接Debug起來;整個過程花了我兩個多小時。記錄一下避免後人踩坑。
有幾個步驟。
1.加入標頭檔案路徑,這個在makefile檔案可以找到。
-I src/core \ -I src/event \ -I src/event/modules \ -I src/os/unix \ -I objs \ -I src/http \ -I src/http/modules
2.1 直接刪掉其他平臺的程式碼,比如win,linux非macos部分。
2.2 刪掉其他makefile檔案中沒有的.c、.cpp檔案。這個還是寫個程式來做吧,如下。
import java.io.*; import java.nio.CharBuffer; import java.util.*; public class FilterCppsInMakefile { private static String srcRoot = "/Users/jjchen/cpro/nginx-test/src"; private static String MakefilePath = "/Users/jjchen/cpro/nginx-master/objs/Makefile"; private static Map<String,String> cppFiles = new HashMap<>(); public static void GetCppFiles(String dirPath){ File dir = new File(dirPath); if (!dir.isDirectory()){ throw new RuntimeException("can not read path: "+dirPath); } File []srcs = dir.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { if (pathname.isDirectory()){ GetCppFiles(pathname.getPath()); return false; } return pathname.getName().endsWith(".c")||pathname.getName().endsWith(".cpp"); } }); for (File src: srcs){ cppFiles.put(src.getName().replace(".c","").replace(".cpp",""),src.getAbsolutePath()); } } public static String read (String filePath)throws Exception{ Reader reader = new BufferedReader(new FileReader(filePath)); StringBuilder stringBuilder = new StringBuilder(); String part = ""; while((part =((BufferedReader) reader).readLine())!= null){ stringBuilder.append(part); } return stringBuilder.toString(); } publicstatic void deleteSrcFiles(List<String>fileList){ for(String fileName : fileList) { for (int i=0; i<2;i++){ File file = new File(fileName); if (!file.exists()) { continue; } else { if (file.isFile()) file.delete(); } //同時刪除標頭檔案 fileName = fileName.replace(".cpp",".h").replace(".c",".h"); } } } public static void main(String[] args) { GetCppFiles(srcRoot); String content = ""; try { content = read(MakefilePath); } catch (Exception e) { e.printStackTrace(); return; } System.out.println(cppFiles.toString()); List<String> delList= new ArrayList<>(); Iterator<HashMap.Entry<String,String>> iterator = cppFiles.entrySet().iterator(); while (iterator.hasNext()){ HashMap.Entry<String,String> node = iterator.next(); if(!content.contains(node.getKey())){ delList.add(node.getValue()); } } System.out.println(cppFiles.size()); System.out.println(Arrays.toString(delList.toArray())); deleteSrcFiles(delList); } }
-
匯入正則的庫,我本地的標頭檔案 /usr/local/Cellar/pcre/8.41/include/,靜態庫libpre.a;
-
執行完make以後,將objs資料夾下的ngx_modules.c檔案和兩個標頭檔案拷入程式碼。
做完這些就可以正常啟動了。去掉空的資料夾只剩下如下的模組。

image.png