天天看點

[記錄點滴]授人以漁,從Tensorflow找不到dll擴充到如何排查問題[記錄點滴]授人以漁,從Tensorflow找不到dll擴充到如何排查問題

[記錄點滴]授人以漁,從Tensorflow找不到dll擴充到如何排查問題

0x00 摘要

本文将通過一個經典的 “tensorflow找不到dll” 問題來入手,給大家一個如何找到缺失dll的辦法,進而再分享一個windows上排查問題的好工具(因為大多開發者在windows上開發&在linux上部署,windows還是繞不過)。

0x01 引言

很多朋友在windows上安裝tensorflow之後,第一次運作會遇到如下錯誤:

ImportError: DLL load failed: 找不到指定的子產品。           

複制

大家第一反應就是去網上搜尋,比如常見的解決辦法是:

  • 運作環境不全,安裝vc_redist.x64.exe即可,比如在

    tensorflow

    官方的

    release note

    中有提示。
  • 安裝visual studio2017。
  • 由于tensorflow 2.1.0 版本較高,需要安裝 CUDA、cuDNN神經網絡加速庫等,直接降版本。
  • ......

很多朋友解決了這個問題就繼續運作tensorflow了,沒有繼續思考這個問題。

其實,絕大多數問題原因是:tensorflow運作環境缺少庫, msvcp140_1.dll, 或者 VCRUNTIME140_1.dll,而vc_redist.x64.exe就是安裝了這個庫,visual studio2017則剛好有運作tensorflow必須的運作時環境。

但是進而有幾個新問題:

  • 如何知道缺少哪個dll?因為我實驗了兩台電腦,一台提示缺少msvcp140_1.dll,一台沒有任何提示,最後發現是缺少VCRUNTIME140_1.dll。
  • 如果新版本tensorflow又缺少其他的dll怎麼辦?
  • 如果其他軟體缺少dll怎麼辦?
  • 如果在windows上遇到其他古怪的問題怎麼辦?

是以我們的終極目标是:

  • 如果某個軟體也出現缺少dll的情況,我們應該有辦法知道缺少哪個dll
  • 如果在windows上遇到其他古怪問題,我們應該知道有什麼工具來幫我們解決。

下面就讓我們解答這兩個問題。

0x02 如何找到缺失的dll

面對缺失的dll,我們的辦法是:祭出 Process Monitor 大招。

Process Monitor是一款 Windows 系統和應用程式監視工具,總體來說,Process Monitor相當于Filemon+Regmon,其中的Filemon專門用來監視系統 中的任何檔案操作過程,而Regmon用來監視系統資料庫的讀寫操作過程。

有了Process Monitor,使用者就可以對系統中的任何檔案和 系統資料庫操作同時進行監視和記錄,通過系統資料庫和檔案讀寫的變化, 對于幫助診斷系統故障或是發現惡意軟體、病毒或木馬來說,非常有用。

Process Monitor 由優秀的 Sysinternals 開發,并且目前已并入微軟旗下,可靠性自不用說。

2.1 Process Monitor可以捕獲哪些事件?

Process Monitor 雖然可以捕獲 Windows 作業系統中的大多數操作資料,但并非抓取每條資訊。它所做的隻是獲得特定類型的 I/O(輸入/輸出)操作,其中就包括:檔案系統、網絡通訊和系統資料庫。當然它還會額外跟蹤其它比較有限幾種事件,例如:

  • 系統資料庫:監控系統資料庫的建立、讀取、删除或查詢操作。
  • 檔案系統:監控本地磁盤或網絡驅動器中檔案的建立、寫入、删除等操作。
  • 網絡:監控程序的 TCP/UDP 源和目标及流量。
  • 程序:可以被動監控程序和線程的活動,包括線程的啟動或退出等。不過通常情況下我們都使用 Process Explorer 來監控程序。
  • 性能分析:Process Monitor 還可以捕獲程序的 CPU 時間和記憶體使用,通常情況下這些資訊我們也主要依賴 Process Explorer 來監控分析。

總的來說,Process Monitor 可以捕獲和監控 Windows 中的 I/O 操作,雖然它不記錄實際對系統資料庫、檔案系統或網絡傳輸中的資料,但我們可以監控到程序的所有操作事件

2.2 Process Monitor預設列

Process Monitor 的預設列中顯示了微軟認為對使用者最為有用的常用資訊,其中從左到右分别為:

  • Time:此列對應每行,顯示該事件發生的精确時間。
  • Process Name:此列顯示的為生成該事件的程序名稱,預設該列隻顯示程序所對應的 exe 檔案名稱,如果将滑鼠指向某個程序名則會懸浮顯示該 exe 在磁盤中的具體路徑。
  • PID:這個不用多說吧,就是程序 ID。
  • Operation:該列記錄的是該事件中所執行的操作名稱,主要比對對系統資料庫、檔案、網絡和程序的操作。
  • Path:此列記錄的是此事件操作路徑,非程序的路徑。例如:WriteFile 事件在此路徑中記錄的是操作的檔案或檔案夾路徑,如果是系統資料庫事件則會記錄所操作的注冊路徑。
  • Result:此列記錄的為該事件操作結果,主要狀态有SUCCESS(成功)或ACCESS DENIED(通路拒絕)等。
  • Detail:此列記錄一些事件操作的額外細節資訊,通常不對排錯起太大意義。
[記錄點滴]授人以漁,從Tensorflow找不到dll擴充到如何排查問題[記錄點滴]授人以漁,從Tensorflow找不到dll擴充到如何排查問題

當然,以上這些列隻為 Process Monitor 提供的預設列,如果你覺得不夠的話可以在列名上右鍵 — 選擇 Select Columns 來自定義選擇所需的列。

2.3 排查過程

下文的實驗環境是缺少msvcp140_1.dll,我們假設沒有提示dll檔案名字。因為因為我實驗了兩台電腦都安裝同樣版本tensorflow,一台提示缺少msvcp140_1.dll,一台沒有任何提示,最後發現是缺少VCRUNTIME140_1.dll。

2.3.1 實驗代碼

import tensorflow as tf
print(tf.version)           

複制

錯誤如下:

File "C:\Users\xxx\AppData\Local\Programs\Python\Python37\lib\site-packages\tensorflow\python\platform\self_check.py", line 61, in preload_check
    % " or ".join(missing))
ImportError: Could not find the DLL(s) 'msvcp140_1.dll'. TensorFlow requires that these DLLs be installed in a directory that is named in your %PATH% environment variable. You may install these DLLs by downloading "Microsoft C++ Redistributable for Visual Studio 2015, 2017 and 2019" for your platform from this URL: https://support.microsoft.com/help/2977003/the-latest-supported-visual-c-downloads           

複制

2.3.2 初步上手

打開 Process Monitor,我們可以看到有很多python.exe的事件

[記錄點滴]授人以漁,從Tensorflow找不到dll擴充到如何排查問題[記錄點滴]授人以漁,從Tensorflow找不到dll擴充到如何排查問題

2.3.3 篩選Process Monitor資料

我們可以用非常顆粒化的過濾器來篩選 Process Monitor 所捕獲的事件,這非常有利于我們對單個程序所生成的事件進行分析。例如當我們隻關心 python.exe 所生成的事件時,隻需将其過濾出來即可。

[記錄點滴]授人以漁,從Tensorflow找不到dll擴充到如何排查問題[記錄點滴]授人以漁,從Tensorflow找不到dll擴充到如何排查問題

當我們選擇 include ‘python.exe’ 之後,界面中則會隻篩選出 python.exe 進行的相關事件。

我們這時候發現,現在事件分為兩種:

  • 對系統資料庫的操作。
  • 對檔案系統的操作。
[記錄點滴]授人以漁,從Tensorflow找不到dll擴充到如何排查問題[記錄點滴]授人以漁,從Tensorflow找不到dll擴充到如何排查問題

對于我們這個例子來說,系統資料庫操作沒啥意義,是以我們隻關心對檔案系統的操作。但是這樣事件也太多了,是以我們隻篩選出沒有找到檔案的資料,即Result 是 NAME NOT FOUND的事件。

2.3.4 Filter

于是我們建立兩個Filter來篩選事件。

一個是指定程序名字是python.exe。

一個是指定Result是NAME NOT FOUND。

[記錄點滴]授人以漁,從Tensorflow找不到dll擴充到如何排查問題[記錄點滴]授人以漁,從Tensorflow找不到dll擴充到如何排查問題

建立的filter如下:

[記錄點滴]授人以漁,從Tensorflow找不到dll擴充到如何排查問題[記錄點滴]授人以漁,從Tensorflow找不到dll擴充到如何排查問題

結果可以看出來,python.exe 在很多目錄下查找 msvcp140_1.dll。這就是python在path中所有路徑下查找這個檔案。

[記錄點滴]授人以漁,從Tensorflow找不到dll擴充到如何排查問題[記錄點滴]授人以漁,從Tensorflow找不到dll擴充到如何排查問題

2.3.5 檢視單個事件

我們可以輕按兩下 Process Monitor 中的任意一條事件來檢視其詳細資訊。

輕按兩下打開 Event(事件) 标簽,其中将列出該事件的詳細時間、事件類型、事件所執行的操作、操作路徑及事件的執行結果等内容。

[記錄點滴]授人以漁,從Tensorflow找不到dll擴充到如何排查問題[記錄點滴]授人以漁,從Tensorflow找不到dll擴充到如何排查問題

當我們切換到 Process(程序) 頁籤之後,則可以看到生成該事件的程序的大量相關資訊。

[記錄點滴]授人以漁,從Tensorflow找不到dll擴充到如何排查問題[記錄點滴]授人以漁,從Tensorflow找不到dll擴充到如何排查問題

而在 Stack(堆棧) 标簽中,我們可以檢視到該事件程序的堆棧,通過該頁籤我們可以檢查任何不正常的子產品。舉個例子,假設某個程序不斷嘗試查詢或通路不存在的檔案,但我們不知道為什麼會發生這種情況。此時,便可以通過檢視 Stack(堆棧) 标簽來檢視是否有任何不正常的子產品。

[記錄點滴]授人以漁,從Tensorflow找不到dll擴充到如何排查問題[記錄點滴]授人以漁,從Tensorflow找不到dll擴充到如何排查問題

2.3.6 總結

現在我們知道是python.exe 在很多目錄下查找 msvcp140_1.dll。我們就可以去網上搜尋這個dll,直接拷貝到系統目錄下即可。

同時我們也初步了解了如何通過 Process Monitor 來查找一個缺失的dll。

0x03 Linux下怎麼辦?

3.1 Linux 版本

可能有人會問,在windows下有process monitor可以監控各種事件,那麼在linux下如果有類似需求,我應該如何處理?

微軟貼心的提供了一個Linux版本,而且開源了 https://github.com/Microsoft/Procmon-for-Linux。

其簡介是:

Process Monitor (Procmon) is a Linux reimagining of the classic Procmon tool from the Sysinternals suite of tools for Windows. Procmon provides a convenient and efficient way for Linux developers to trace the syscall activity on the system.

但是這個就不是綠色版本了,而是需要自己編譯安裝。

3.2 用法舉例

具體用法舉例如下:

  • 跟蹤系統所有程序和系統調用
sudo procmon           

複制

  • 跟蹤程序号10和20的程序
sudo procmon -p 10,20           

複制

  • 隻跟蹤程序号為20的程序的如下系統調用: read, write and openat
sudo procmon -p 20 -e read,write,openat           

複制

  • 跟蹤程序35,并且把所有事件輸出到procmon.db
sudo procmon -p 35 -c procmon.db           

複制

3.3 螢幕示例

具體螢幕示例如下:

[記錄點滴]授人以漁,從Tensorflow找不到dll擴充到如何排查問題[記錄點滴]授人以漁,從Tensorflow找不到dll擴充到如何排查問題

目前為止,我們知道了如何排查dll缺失。但是在windows上如果遇到了其他古怪問題,我們應該怎麼處理呢?下面我們繼續了解一個排查神器。

0x04 一個給力的排查神器

下面文字幾乎都摘錄 SysInternals系列:什麼是SysInternals工具集 這個系列。

4.1 SysInternals

我們之前提到Process Monitor 屬于SysInternals,那麼我們下面為大家推薦的排查神器就是SysInternals套件。

SysInternals 工具集最早由大牛 Mark Russinovich 開發,它是一套完全免費的 Windows 工具套件,其官方網站為 www.SysInternals.com 。由于已經于 2006 年被微軟收購,Mark 也已經出任 Aazure CTO,通路網址時會直接跳轉到 Technet 的 SysInternals 首頁。

該工具集在平常的維護和排錯工作中經常都會用到,微軟的 Troubleshooting 團隊也會經常使用該工具集中的工具。正是由于其強大的功能和便利性,被微軟收購也不足為奇了。SysInternals 工具集的工具有很多,大概涵蓋了如下的幾個類型:

  • 檔案和磁盤工具
  • 網絡工具
  • 程序工具
  • 安全工具
  • 系統資訊工具
  • 其它類型工具

Sysinternals 套件可以免費從微軟 Technet 網站下載下傳,而且都是綠色版無需安裝,大家可以放到 U 盤中随身攜帶,非常友善。

4.2 功能簡介

因為大家不是專業的windows運維,是以隻要快速浏覽,大概知道此神器有哪些功能,遇到問題時候知道搜尋什麼關鍵字即可。最重要的是知道有這個神器,知道搜尋什麼内容。

4.2.1 Process Explorer

Process Explorer 是一個類似于任務管理器和資源螢幕的應用,它自 2001 年首次釋出以來曆經了 Windows 9x 至支援 Windows 10 的各種 Windows 版本,目前微軟還在不斷的更新和改進,是我們日常處理故障和排錯的必備利器。

下面列舉了 Process Explorer 一些常用功能及特性清單,有許多非常有用的功能都掩藏在其不起眼的界面之下,很多時候一個很小的功能和特性就能夠幫我們在排錯時少走彎路和節約時間,大家一定要用心去發覺。

  • 它預設以程序樹的方式顯示程序及子程序之間的關系(可開關)且以顔色進行區分讓人一目了然
  • 非常精确的 CPU 占用顯示
  • 提供替代任務管理器的選項,在 Windows XP/7/Vista/8/10 中都非常有用
  • 可以工作列托盤圖示的方式監視 CPU、磁盤、GPU 和 網絡等的使用情況
  • 檢視程序加載了哪些 DLL
  • 檢視程序打開或鎖定了哪些檔案或檔案夾
  • 檢視任何程序的完整資訊,包括:線程、記憶體占用、句柄、對象和其它幾乎任何你想知道的内容
  • 可以直接 Kill 掉整個程序樹
  • 可以将程序挂起(暫停),當機其所有線程
  • 強大到可以檢視線程的CPU使用率
  • 從 v16 版本開始內建了VirusTotal,可以快速驗證是否是病毒

4.2.2 PsTools

PsTools 可以幫助我們在指令行中執行相當多的管理任務,更主要的是可以将其寫成腳本來執行周期性重複任務或在管理大批量伺服器時提高效率。

作為 Sysinternals 工具包中的一個子集,PsTools 本身就有十來個指令行小工具,下面我們會逐個為大家進行介紹:

  • PsExec – 在遠端計算機執行指令
  • PsFile – 檢視打開的網絡檔案
  • PsGetSid – 擷取 Machine SID
  • PsInfo – 檢視簡要系統資訊
  • PsKill – 按程序名或PID殺掉程序
  • PsList – 列出程序資訊
  • PsLoggedOn – 顯示已登的會話
  • PsLogList – 指令行擷取 event log
  • PsPasswd – 更改使用者密碼
  • PsPing – 簡單的tcp/udp連接配接測試工具
  • PsService – Windows 服務管理指令
  • PsShutdown – 關機、登出指令
  • PsSuspend – 暫停或恢複某個程序

以上所有指令都可以直接在本地計算機上使用。

4.2.3 TCPView

TCPView 是用于檢視目前 Windows 應用程式和服務連網狀态的絕佳工具,通過它我們可以在圖形界面中檢視到類似使用 netstat 指令輸出的大部分資訊。

4.2.4 ListDlls

與 Process Explorer 的功能類似,ListDlls 主要用于顯示程序載入的 DLL 檔案,當然 Process Explorer 更直覺易用。

4.2.5 RamMap

RamMap 工具主要用于分析實體記憶體的使用情況,它以可視化的圖形界面進行輸出顯示。在 RamMap 界面中,你可以檢視到非常詳細的記憶體用量,例如:空閑記憶體、頁面緩沖池、非頁面緩沖池、已送出和已緩存等條目的詳細情況,比任務管理器中的記憶體顯示強大多了。

4.2.6 Handle

Handle 指令行工具的功能其實在 Process Explorer 中也有,使用它可以快速找出程序所打開的資源句柄。

4.2.7 Autologon

Autologon 就是可快速實作 Windows 自動登入的第三種工具。

4.2.8 RegJump

RegJump 指令行工具可以很快在系統資料庫樹狀條目中進行定位(完全支援簡寫)

4.2.9 ShellRunAs

ShellRunAs 指令行工具其實是一個 Shell 擴充應用,它可以讓我們快速以不同使用者身份來執行應用。

4.2.10 AccessEnum

AccessEnum 是在做檔案夾權限排錯時最常用的一個工具,在我們對某個檔案夾進行過複雜的權限配置後,AccessEnum 工具可以非常容易幫助我們理清檔案夾或系統資料庫的最終通路控制清單。

4.2.11 Streams:檢視和顯示隐藏的NTFS流

大多數使用者都不了解,Windows 其實會隐藏部分存儲在檔案系統中的資料,被稱為「備用資料流」,隻有在檔案名末尾追加冒号和獨特的密鑰才能與之進行互動。

Streams可以幫助大家檢視指定檔案已有的全部「備用資料流」

4.2.12 SigCheck:分析未經數字簽名的檔案(如惡意軟體)

SigCheck 也是可以幫助我們分析檔案是否擁有數字簽名的一個指令行工具。它還可以從 VirusTotal 進行檢查,以友善我們找出惡意軟體。

4.2.13 SDelete:安全删除檔案

大家都知道,在 Windows 中删除檔案都不是直接清除,而是在硬碟中标記為已删除,SDelete 指令行工具可以幫助我們将硬碟中已經删除檔案部分填充無意義資料以達到抹除的目的。

4.2.14 Contig:整理一個或多個檔案

如果你想隻對 Windows 中的一個或幾個檔案進行磁盤碎片整理,可以使用 Contig 指令行工具

4.2.15 du:檢視磁盤用量

相信大家最常用 Windows 資料總管來檢視磁盤空間和檔案夾大小,而 du 是 Sysinternals 套件中的指令行磁盤和檔案夾大小檢視工具。

4.2.16 Junction:建立符号連結

Windows 與 Linux 一樣支援檔案和檔案夾的符号連結,Sysinternals 工具包中的 Junction 指令也可用于建立和删除符号連結。

4.2.17 DiskView:顯示磁盤結構

DiskView 小工具可以讓你以圖形界面的方式檢視詳細的磁盤驅動器結構并可以放大和縮小顯示區塊,甚至可以選擇某個檔案之後檢視其在磁盤中存儲的位置。

4.2.18 MoveFiles:重新開機時移動系統檔案

大家有沒想過為什麼在 Windows Update 之後或安裝某些應用程式之後會要求重新開機系統?因為在 Windows 運作時,有些檔案(特别是系統檔案)是不能随便被移來移去功随意替換掉的。movefile 指令行小工具可以調用 Windows 自身的功能幫助我們在 Windows 下次重新開機時移動、删除或重命名檔案或目錄

4.2.19 FindLinks:查找硬連結檔案

前面既然提到了 Junction 建立符号連結,就不得不提一個 findlinks 這個 Sysinternals 是用于檢視檔案硬連結的指令行工具。如果有多個硬連結指向同一檔案,在删除最後一個硬連結時就會将檔案直接删除,是以大家可用 findlinks 工具進行檢視和關注。

4.2.20 Disk2vhd:實體磁盤轉換VHD虛拟磁盤

Disk2vhd 小工具可将正在運作計算機的磁盤克隆成 VHD 虛拟磁盤檔案,是以它也成為不少虛拟化項目中的 P2V 轉換工具。

0xFF 參考

病毒分析(三)-利用Process Monitor對熊貓燒香病毒進行行為分析

利用Process Monitor軟體解決無法加載DLL檔案的問題

SysInternals系列:什麼是SysInternals工具集

SysInternals系列:使用Sysmon将監控事件寫入系統日志

SysInternals系列:其它常用工具介紹

SysInternals系列:使用PsTools工具執行本地/遠端PC管理任務

SysInternals系列:分析管理檔案、檔案夾和驅動器

SysInternals系列:Windows啟動項管理利器Autoruns

Process Explorer:Windows程序管理及排錯利器(上)

Process Explorer:Windows程序管理利器常用功能(中)

Process Explorer:診斷和排錯執行個體(下)

Process Monitor:Windows事件監控利器簡介(上)

Process Monitor:Windows事件監控常用功能(中)

Process Monitor:Windows事件監控執行個體(下)

Process Monitor(簡稱Procmon)釋出Linux版,附使用方法

https://github.com/microsoft/ProcMon-for-Linux