日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

访问进程环境变量environ时的一个坑

發布時間:2025/3/15 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 访问进程环境变量environ时的一个坑 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在unistd.h中定義了變量char **environ;來表示當前所有環境變量,一般來說訪問特定環境變量可以用getenv,但是想遍歷所有環境變量就得使用environ。

即在程序內全局聲明extern char **environ;當然設定main函數第3個參數也可以,不過不推薦,因為ISO C的main函數沒有第三個參數。

environ維護了一個char*數組,每個元素都是一個指針指向函數棧幀頂部的環境變量,數組結尾是NULL。

于是正確的遍歷姿勢是下面這樣

for (int i = 0; environ[i] != NULL; i++)puts(environ[i]);

然后我試了下錯誤的姿勢

for (char *ptr = environ[0]; ptr; ptr++)puts(ptr);

結果是程序dump了,審查了下發現錯誤出在ptr++上,因為ptr類型是char*,執行++后指針只向前移動1 byte。

于是就變成這樣

for (char *ptr = environ[0]; ptr; ptr += (strlen(ptr) + 1)puts(environ[i]);

代碼已經比較丑陋了,而且還多出了不必要的計算,即strlen函數,但是程序依然dump了。

我的調試方式是這樣的

for (char *ptr = environ[0]; ptr; ptr += (strlen(ptr) + 1)){static int i = 0;if (strcmp(ptr, environ[i]) != 0){printf("error: %d\n", i);break;}puts(ptr);i++;}

?錯誤如下

Program received signal SIGSEGV, Segmentation fault. __strcmp_sse2_unaligned () at ../sysdeps/x86_64/multiarch/strcmp-sse2-unaligned.S:204 204 ../sysdeps/x86_64/multiarch/strcmp-sse2-unaligned.S: No such file or directory.

對啊,environ數組最后一個元素是NULL,但是strcmp必須接收非NULL指針作為參數(因為strcmp的參數s1、s2必須可以用*s1、*s2來訪問,NULL是地址0,是用戶無法訪問的地址,用戶訪問無法訪問的地址時就會產生SIGSEGV信號)。

于是我定位到了strcmp這句

(gdb) b 15 if environ[i]==0 (gdb) p ptr $1 = 0x7fffffffefe3 "/home/xyz/TLPI/a.out" (gdb) p environ[i] $2 = 0x0

?原因也清楚了。在C程序的存儲空間高地址是命令行參數和環境變量依次排列,如下圖

n1是環境變量的數量,n2是命令行參數的數量。因此在ptr指向最后一個環境變量時,ptr+=(strlen[ptr]+1)后指向的是argv[0]。

字符指針數組environ保存了n1+1個元素,多出一個元素是NULL。而ptr+=(strlen[ptr]+1)則是直接訪問程序的存儲空間,并沒有一個終止符。

當ptr到達內存中不可訪問的區域(即argv[n2-1]的下面,函數棧幀的地址),就會引發SIGSEGV信號。

轉載于:https://www.cnblogs.com/Harley-Quinn/p/6817958.html

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的访问进程环境变量environ时的一个坑的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。