---
# System prepended metadata

title: 'Lecture 7: Debugging and Profiling (2020)'
tags: [FreeCodeCamp]

---

###### tags: `FreeCodeCamp`
Lecture 7: Debugging and Profiling (2020)
===
[link](https://www.youtube.com/watch?v=l812pUnKxME&t)

- 在scrit中可以使用不同的色塊來改變輸出顏色。

- 小的程式常常會用printf來查看東西的錯誤，但有時候程式大了會出現很多，這時候就會善用log這部分來處理相關的訊息，來查看程式中的一些設定。可以在/var/log中找到資訊。

- system log 可以看到有關system的相關資訊。
大部分的system log會被彙整起來。
journalctl可以看，Mac就要使用Log show 。
- log show -- 10s (可以看十秒前的東西)

## 查詢 LOG
```
logger "hello logs"
log show --last 1m | grep Hello
```
用上訴的指令可以找到Hello logs在log裡面出現的時間。

- LOG可以幹嘛?
	- 轉換WIFI的網路時候，可以找到自己登陸不同WIFI的紀錄
	- 若是有台電腦主機被休眠(hibernation mode)，可以在log上方找到誰對他下了這個指令跟紀錄 


## fix bug
- 若Python出問題時，可以使用ipdb來做偵錯
```
python -m ipdb bubble.py
```
ipdb is iPython debugger

```
l
```
這個狀態之下可以打l就會列出所有的行數。 

```
s
```
這個狀態下打s就是一個step，可以讓程式一行一行的執行。

```
c
```
用此指令可以直接去有問題的地方修復那些程式碼

```
p j
p arr
```
可以用此把j 顯示出來
下方是可以把那個array顯示出來(若代表array)

```
b 6 
```
這樣會在第六行設定了一個breakpoint，可以去檢查第六行執行時候的狀況。可以用c繼續然後用s一步步往下。

## kernel專用檢查

```
gdb --args sleep 20
```
把sleep這個指示用gdb的方式載入

```
run
```
開始檢視指令內部最深層的機器指令，一般用於C開發都會用這樣處理。


```
sudo strace ls -l > /dev/null
```
strace會用來做system log的觀察，很好用


## 測試工具
- pyflake
```
pyflake lint.py
```
lint.py這個檔案被pyflake來偵測，可以找尋一些潛在的問題跟狀況。
pyflake是一個可以找尋潛在問題的模組，這樣使用就可以找到資訊。

- mypy
```
mypy lint.py
```
一樣對lint.py做基礎的分析跟測試，但麻煩的是會針對一些data type做提醒(float、int之類的調整)

## static analyzer
- writegood
```
writegood notes.md
```
writegood可以使用在一些文件分析上，他可以做出一點貢獻跟建議

- inspect element on web
網頁上的css、html前端的頁面都是可以更改的，只要用debug模式即可，所以是不要相信任何網站截圖的資訊，因為都是可以改的。

網頁其實都有內建Javascript的debugger，所以可以用那些inspect的物品來做debug。

- 印出時間
```
start=time.time()

# Do some work
print("sleeping for {} s".format(n/1000))
time.sleep(n/1000)

#compute time between start and now

print(time.time() - start)

```
這樣print出來 sleeping 的時間會有點差距，因為kernel跑跟用cpu的時間會有一點差。

- time
```
time curl www.google.com.tw
```
curl是一個可以在linux系統中存取網頁的指令，相關細節可以看[這裡](https://blog.techbridge.cc/2019/02/01/linux-curl-command-tutorial/)。
上述指令會拿到抓取這個網頁的整體時間，顯示如下
```
real 0m0.605s
user 0m0.016s
sys  0m0.009s
```
real是程式開始到最後結束的時間
user是整體在cpu裡面經過的時間(user level)
 sys是在整個kernel裡面的時間(kernel level)
 
看起來大部分的時間都是在等對方的伺服器回應跟給資訊
總共占用CPU的時間只有0.016+0.009。


## Profile 效能分析
```
python -m cProfile -s tottime grep.py 1000 '^(import|\s*def)[^,]*$' *.py

```

執行一千次，算出totaltime(tottime)
profile會顯示在不同階段花地個別時間，就可以針對這些時間的使用來做不同的程序優化。



- cprofile
```
# urls.py
from bs4 import BeautifulSoup

#this is a decorator that tells line_profiler
#that we want to analyze this function
#@profile

def get_urls():
	response = requests.get('https://missing.csail.mit.edu')
	s = BeautifulSoup(response.content, 'lxml')
	urls = []
	for url in s.find_all('a'):
		urls.append(url['href'])
		
if __name__ == '__main__':
	get_urls()

```
用linux執行上述檔案

```
python -m cProfile -s tottime urls.py |tac

```

tac 可以將整個程序分析的行列倒過來顯示。


- kernprof 效能分析
```
kernprof -l -v urls.py
```
這可以逐行顯示你的效能，這也是一個很不錯的

- memory 的效能分析

```
@profile
def my_func():
	a=[1]*(10 ** 6)
	b=[2]*(2 * 10 ** 7)
	del b
	return a

if __name__ == '__main__':
	my_func()
```

然後用linux指令

```
python -m memory_profiler mem.py
```

這樣可以查看各個memory的使用狀況，若是有從網路上抓人家code下來的狀況發現執行能力差，也可以用這個方式來改善memory的使用效能。
透過逐行執行來檢查。

- 檢查使用
```
sudo perf stat stress -c 1
```
this stress code only run in cpu
and we can use ctrl c to go back to check the resource we use

```
sudo perf record stress -c 1
```

```
sudo perf report
```
這可以產出報告，可以看到所有的資訊跟資源使用的百分比例。


- call graph
use call graph can explain which piece of your code is calling this really expensive IO operation

- top
use top can see your IO operation and the total consumpotion of your cpu and memory.

- disk resource visit
```
du -h videos
```

we can get the output of the size in this folder.
-h mean use it in a human readable way

```
ncdu.
```
ncdu is an interactive way to browse your file and their file memory consumption in disk

- python server

```
python -m http.server 4444
```

或是利用 lsof (必須要用SUDO，因為需要用到的資料很多)

```
sudo losf | grep ":4444 .LISTEN"

```
上述程式會顯示在聽port 4444的那隻程式。
```
kill 25031
```
kill 這隻程式。

- hyperfine
可以比較兩個程序的速度快慢
```
hyperfine --warmup 3 'fe -e jpg' 'find . -iname "*.jpg"'

```
這樣可以比較fd跟find的速度差別。

## 程序
若是要怎樣判斷程式異常，過長的讀取要去看內容。
還是始終看你做甚麼，若是http的request讀取，一般而言不會太長。但若是複雜的數學問題，可以用上面的方式拆成細碎的地方去看，去找尋更細部地方的不合理之處做修改或改正。