cppdcc同人圖與草坪拼音

本文將介紹一些在開(kāi)發(fā)多 Linux 平臺(tái) C++ 應(yīng)用時(shí)可能遇到的兼容性問(wèn)題和相關(guān)的解法。雖然是以 C++ 為講述對(duì)象,但兼容性這個(gè)問(wèn)題,在沒(méi)有 VM 幫你做這些臟活累活的情況下,是所有 C-like 語(yǔ)言(比如 Go、Rust 等)都可能遇到的。

受個(gè)人經(jīng)驗(yàn)所限,本文所討論內(nèi)容僅限于 x86 架構(gòu)下,但相信相關(guān)的原理和規(guī)則在其他架構(gòu)下也是相通的,可作借鑒參考。

Linux 二進(jìn)制兼容

首先,我們來(lái)看看什么叫二進(jìn)制兼容?

眾所周知,不同的 Linux 發(fā)行版會(huì)攜帶不同的基礎(chǔ)庫(kù)版本,以最常用的 g++ 工具鏈為例,基于它們的應(yīng)用會(huì)附帶地依賴上 libc, libgcc, libstdc++ 等庫(kù)。顯然,當(dāng)應(yīng)用使用了高版本才具備的功能后,編譯得到的二進(jìn)制內(nèi)容在低版本環(huán)境中運(yùn)行時(shí),將產(chǎn)生兼容問(wèn)題,最常見(jiàn)的表現(xiàn)就是無(wú)法運(yùn)行

簡(jiǎn)而言之,當(dāng)所提供的應(yīng)用 binary 在目標(biāo)平臺(tái)上無(wú)法正常運(yùn)行(包括跑不起來(lái)這種最差的情況),我們就認(rèn)為這是一種不兼容的情況。

多平臺(tái)兼容的常用方法

為了讓?xiě)?yīng)用兼容多平臺(tái),從開(kāi)發(fā)者的角度一般有以下三個(gè)方法 [1]。

1. 為每個(gè)目標(biāo)平臺(tái)提供特定的 Binary

顧名思義,對(duì)于每個(gè)目標(biāo)平臺(tái),這種方法都要提供相應(yīng)的 binary。

這種方法的好處在于每個(gè) binary 或是安裝包都能夠?qū)δ繕?biāo)平臺(tái)進(jìn)行針對(duì)性適配,在承諾支持的范圍內(nèi)基本不需要擔(dān)心發(fā)生不兼容的情況。

但這種方式的缺點(diǎn)也很明顯,維護(hù)代價(jià)較大。應(yīng)用每新增一個(gè)目標(biāo)平臺(tái),在發(fā)布流程中就要為之構(gòu)建相應(yīng)的編譯打包環(huán)境,即便是借助一些手段(比如容器鏡像)來(lái)實(shí)現(xiàn)流程自動(dòng)化,維護(hù)諸多的編譯環(huán)境本身也會(huì)帶來(lái)不小的工作量。

2. 低版本環(huán)境編譯

此方法要求開(kāi)發(fā)者將編譯環(huán)境設(shè)置在目標(biāo)平臺(tái)中版本最低的環(huán)境上,此處的版本主要指的編譯工具鏈。比如我們期望提供 CentOS 5.x 到 7.x 都能運(yùn)行的應(yīng)用,那么可以將編譯環(huán)境設(shè)置在 5.0 上。

這個(gè)方法源于對(duì) Linux 向后兼容能力的信任,根據(jù)經(jīng)驗(yàn),在低版本上編譯得到的 binary,在高版本上有很大概率能夠正常運(yùn)行。

此方法的缺陷是應(yīng)用能夠使用的功能受限于編譯環(huán)境,包括所能夠使用的語(yǔ)言特性和系統(tǒng)功能。比如:

如果環(huán)境上的 gcc 工具鏈仍在 4.1.x 版本,我們顯然無(wú)法使用 C++11 等特性。

某些系統(tǒng)庫(kù)(比如 journal)需要更高的內(nèi)核版本支持,那么在低版本環(huán)境下將無(wú)法使用。

3. 靜態(tài)鏈接

嚴(yán)格來(lái)說(shuō),這不算是一個(gè)獨(dú)立解決多平臺(tái)兼容的方法,因?yàn)樗耆梢越Y(jié)合前兩個(gè)方法一并使用,但考慮到這是一個(gè)非常常用的辦法,在此我們簡(jiǎn)單地說(shuō)兩句。

此方法解決兼容問(wèn)題的基本思路是將應(yīng)用所依賴的各種庫(kù)都進(jìn)行靜態(tài)鏈接,這樣在發(fā)布應(yīng)用時(shí)僅需要提供一個(gè)單獨(dú)的 binary,而無(wú)需附帶上一系列關(guān)聯(lián)的動(dòng)態(tài)庫(kù)(so 文件),能夠有效地降低不兼容問(wèn)題出現(xiàn)的概率。

但靜態(tài)鏈接并非萬(wàn)能,拋開(kāi)體積膨脹以外,它還有這樣兩個(gè)問(wèn)題。一方面,有些庫(kù)的 license 中會(huì)限制靜態(tài)鏈接,另一方面,即使我們可以對(duì)大部分庫(kù)進(jìn)行靜態(tài)鏈接,但隨系統(tǒng)發(fā)布的 libc.so [2] 是無(wú)法這樣做的,它也會(huì)帶來(lái)一些兼容問(wèn)題 。

我們的多平臺(tái)兼容思路

本節(jié)將簡(jiǎn)要介紹在開(kāi)發(fā) Logtail(SLS 采集 agent)的過(guò)程中,我們和多平臺(tái)兼容「斗爭(zhēng)」時(shí)做出的一些選擇。

1. 不排斥高版本編譯器(只要穩(wěn)定)

最初,我們僅采用了方法 2 來(lái)做到盡可能地兼容多平臺(tái),效果很好。但隨著 C++ 標(biāo)準(zhǔn)的不斷演進(jìn),我們面臨了一個(gè)直接問(wèn)題:低版本環(huán)境「落后」的語(yǔ)法支持和日益了解的新特性之間的矛盾。在低版本環(huán)境下,由于僅支持 C++98,我們:

沒(méi)法在恰當(dāng)?shù)牡胤揭?move 語(yǔ)義,只能依靠注釋。

重復(fù)地敲打著 auto 就能替換的迭代器類型聲明。

...

但經(jīng)過(guò)調(diào)研和實(shí)踐后,我們發(fā)現(xiàn),其實(shí)只需要借助靜態(tài)鏈接標(biāo)準(zhǔn)庫(kù)+手動(dòng)構(gòu)建編譯工具,就能夠在保證兼容性地情況下,開(kāi)心地使用新特性。

2. 盡可能地靜態(tài)鏈接(注意版權(quán))

雖然靜態(tài)鏈接會(huì)導(dǎo)致 binary 產(chǎn)生一定程度的體積膨脹,但相比它能夠帶來(lái)的兼容能力的提升,這些額外的空間開(kāi)銷我們認(rèn)為是值得的。

對(duì)于版權(quán),豐富的開(kāi)源生態(tài)并沒(méi)有讓我們失望,暫未遇到任何這方面的限制。

3. 符號(hào)替換

細(xì)數(shù)我們所遇到的兼容性問(wèn)題,大多數(shù)都是在運(yùn)行環(huán)境中缺失所需符號(hào)或是符號(hào)版本不一致導(dǎo)致的,此時(shí)符號(hào)替換將是一個(gè)很好的解決思路,事實(shí)上,我們也是借此方法來(lái)解決 libc.so 帶來(lái)的一些問(wèn)題。

操作實(shí)踐

對(duì)于一篇實(shí)踐類的文章,單純使用文字來(lái)介紹總是匱乏的,也無(wú)法清楚地描述實(shí)際的問(wèn)題。因此,本節(jié)將通過(guò)一個(gè)示例來(lái)對(duì)前述內(nèi)容進(jìn)行補(bǔ)充說(shuō)明。

示例應(yīng)用代碼

在示例應(yīng)用中,我們使用了 C++11 的一些特性,包括 uniform initialization, lambda (with capture), for auto 等。

#include <iostream> #include <vector> #include <string> #include <algorithm> using namespace std; int main() { vector<string> vec = {"b", "a", "d"}; auto printVec = [&vec]() { for (auto &s : vec) { std::cout << s << std::endl; } }; for (int i = 0; i < 10; ++i) { vec.push_back(to_string(i)); } std::cout << "===== Before =====" << std::endl; printVec(); sort(vec.begin(), vec.end()); std::cout << "===== After =====" << std::endl; printVec(); return 0; }

編譯及運(yùn)行環(huán)境

如下是示例所使用的兩個(gè)環(huán)境,我們將在 CentOS 7 上使用 g++ 4.8.5 對(duì)應(yīng)用進(jìn)行編譯,然后把得到的 binary 放到 CentOS 5 上運(yùn)行。

# 在兩個(gè)環(huán)境上分別運(yùn)行此命令 $ cat /etc/redhat-release; uname -r; g++ --version | grep g++; ld --version | grep ld # 編譯環(huán)境(高版本) CentOS Linux release 7.5.1804 (Core) 3.10.0-862.3.2.el7.x86_64 g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-28) GNU ld version 2.27-27.base.el7 # 運(yùn)行環(huán)境(低版本) CentOS release 5.7 (Final) 2.6.18-274.el5 g++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-51) GNU ld version 2.17.50.0.6-14.el5 20061020

原始版本(v1)

執(zhí)行 g++ -o main_v1 -std=c++11 main.cpp 進(jìn)行編譯,將得到的結(jié)果拷貝到運(yùn)行環(huán)境執(zhí)行,結(jié)果如下:

./main_v1: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.14' not found (required by ./main_v1)

這個(gè)報(bào)錯(cuò)表示所鏈接的 libstdc++.so 無(wú)法滿足版本要求。對(duì)此,分別查看一下 libstdc++.so 和 main_v1 中 GLIBCXX 的版本情況:

$ strings main_v1 | grep "GLIBCXX_" GLIBCXX_3.4.5 GLIBCXX_3.4.14 GLIBCXX_3.4 $ strings /usr/lib64/libstdc++.so.6 | grep "GLIBCXX_" GLIBCXX_3.4 GLIBCXX_3.4.1 ... GLIBCXX_3.4.8 GLIBCXX_FORCE_NEW

可以看到,main_v1 要求 3.4.14 而運(yùn)行環(huán)境上的 libstdc++.so 僅支持到 3.4.8,所以產(chǎn)生了這個(gè)錯(cuò)誤。

對(duì)于這個(gè)問(wèn)題,由于運(yùn)行環(huán)境的不可控,我們無(wú)法通過(guò)更新 libstdc++.so 來(lái)解決,只能通過(guò)修改自己的應(yīng)用來(lái)進(jìn)行兼容。

解決辦法:靜態(tài)鏈接 libstdc++.a。

此處我們使用 nm 來(lái)進(jìn)一步分析 main_v1 究竟依賴了哪些 3.4.14 版本的符號(hào)(配合 c++filt 進(jìn)行 demangle),結(jié)果如下:

$ nm main_v1 | grep "GLIBCXX_3.4.14" U _ZNSsaSEOSs@@GLIBCXX_3.4.14 U _ZNSsC1EOSs@@GLIBCXX_3.4.14 $ c++filt _ZNSsaSEOSs std::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator=(std::basic_string<char, std::char_traits<char>, std::allocator<char> >&&) $ c++filt _ZNSsC1EOSs std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::basic_string<char, std::char_traits<char>, std::allocator<char> >&&)

可以發(fā)現(xiàn),這是與 string 相關(guān)的兩個(gè)以右值引用為參數(shù)的方法,所以在不支持 C++11 的低版本環(huán)境上,libstdc++.so 顯然不可能有這些符號(hào)。

靜態(tài)鏈接 libstdc++(v2)

一般來(lái)說(shuō),編譯環(huán)境中是不會(huì)自帶 libstdc++.a,需要做一些額外的安裝,比如 CentOS 7 可以直接通過(guò) yum 安裝。

如下是做了靜態(tài)鏈接后的運(yùn)行結(jié)果:

# 安裝 + 靜態(tài)鏈接 $ sudo yum install -y libstdc++-static $ g++ -o main_v2 -static-libstdc++ -std=c++11 main.cpp # 運(yùn)行 ./main_v2: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by ./main_v2)

和 v1 類似的錯(cuò)誤,借助同樣的方法可以發(fā)現(xiàn),這次是 libc.so 的版本不支持導(dǎo)致的,main_v2 需要 2.14 而運(yùn)行環(huán)境上僅支持到 2.5。

$ strings main_v2 | grep "GLIBC_" GLIBC_2.3 GLIBC_2.14 GLIBC_2.3.2 GLIBC_2.2.5 $ strings /lib64/libc.so.6 | grep "GLIBC_" GLIBC_2.2.5 GLIBC_2.2.6 GLIBC_2.3 GLIBC_2.3.2 GLIBC_2.3.3 GLIBC_2.3.4 GLIBC_2.4 GLIBC_2.5 GLIBC_PRIVATE

作為一個(gè)隨系統(tǒng)釋出的庫(kù),libc.so 帶來(lái)的兼容性問(wèn)題一般無(wú)法通過(guò)靜態(tài)鏈接解決(理論上或許可行),我們只能尋求其他的方法。

符號(hào)替換(v3)

為了解決 v2 的問(wèn)題,我們先用 nm 看看究竟是哪個(gè)符號(hào)需要 GLIBC 2.14,結(jié)果如下:

$ nm main_v2 | grep "GLIBC_2.14" U memcpy@@GLIBC_2.14

可以看到,只有 memcpy 這一個(gè)符號(hào),直覺(jué)上這個(gè)方法的實(shí)現(xiàn)不太可能跟著版本在不停更新。在查看 glibc 源碼后可以發(fā)現(xiàn),string/memcpy.c 在 2.2.5 -> 2.14 之間都沒(méi)有任何變化。因此,低版本環(huán)境上的 libc.so 其實(shí)已經(jīng)提供了我們需要的 memcpy 的實(shí)現(xiàn),唯一需要解決的就是繞過(guò)版本的檢查。

對(duì)于這一點(diǎn),可以借助 內(nèi)聯(lián)匯編 + 符號(hào)指定 來(lái)實(shí)現(xiàn)。出于篇幅,此處我們直接給出相應(yīng)地解決代碼,具體分析工作可以參考舊版glibc兼容旅程 - CSDN博客。

#ifdef v3 extern "C" { #include <string.h> asm(".symver memcpy, "); void* __wrap_memcpy(void* dest, const void* src, size_t n) { return memcpy(dest, src, n); } } #endif

編譯及運(yùn)行結(jié)果:

$ g++ -o main_v3 -static-libstdc++ -Wl,--wrap=memcpy -Dv3 -std=c++11 main.cpp $ ./main_v3: symbol lookup error: ./main_v3: undefined symbol: _ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE

還是無(wú)法運(yùn)行......我們來(lái)分析一下,顯然,這是一個(gè) C++ mangled 符號(hào),按道理應(yīng)該在我們靜態(tài)鏈接 libstdc++ 時(shí)已經(jīng)解決了,為什么依舊會(huì)出現(xiàn)呢?

搜了一番后發(fā)現(xiàn)了這樣一個(gè)帖子:SERVER-11641 undefined symbol:
_ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE - MongoDB。有興趣的同學(xué)可以細(xì)看一下帖子的內(nèi)容,就基本能理解這個(gè)問(wèn)題了,這里我簡(jiǎn)單地復(fù)述一遍。

我們把 main_v3 拷貝到兩個(gè)環(huán)境中,然后使用 nm 來(lái)查看一下這個(gè)符號(hào):

$ nm main_v3 | grep "_ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE" # 上面的是編譯環(huán)境,下面是運(yùn)行環(huán)境 0000000000680cc0 u _ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE 0000000000680cc0 ? _ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE

可以發(fā)現(xiàn),中間那個(gè)字符有所不同,在高版本的編譯環(huán)境上,中間的符號(hào)是 u,而低版本的運(yùn)行環(huán)境上則是 ?。

從 man nm 中可知,u 表示這個(gè)符號(hào)是 GNU unique global symbol 類型,這是 GNU 對(duì) ELF 的一個(gè)擴(kuò)展,它會(huì)影響到動(dòng)態(tài)鏈接的過(guò)程,換句話說(shuō),它會(huì)影響到 ld 對(duì)動(dòng)態(tài)鏈接過(guò)程的處理。

因?yàn)?ld/nm 等命令也是基礎(chǔ)環(huán)境之一,兩個(gè)環(huán)境上的版本也有不同,低版本的 2.17.50 并沒(méi)有支持這個(gè)擴(kuò)展,所以 nm 查看的結(jié)果顯示為未知(?),而 ld 在做動(dòng)態(tài)鏈接時(shí)會(huì)拋棄掉這種未知的符號(hào),所以也就出現(xiàn)了未定義符號(hào)的問(wèn)題。

對(duì)于這個(gè)問(wèn)題,和 libc.so 一樣,我們也沒(méi)辦法去更新 ld,所以還是只能在編譯環(huán)境中解決此問(wèn)題。解決的思路就是讓 gcc 不要生成這種擴(kuò)展類型的符號(hào),讓運(yùn)行環(huán)境中的 ld 能夠識(shí)別并鏈接它。

不生成 Unique Global Symbol(v4)

對(duì)于這個(gè)需求,從 gcc mail list 的回復(fù)中可以看到,并沒(méi)有這樣的編譯選項(xiàng),唯一可行的途徑是在編譯 gcc 的時(shí)候,指定一個(gè)
--disable-gnu-unique-object
參數(shù),因此,解決辦法就是重新編譯一個(gè) gcc...

$ wget http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-4.8.5/gcc-4.8.5.tar.bz2 $ tar -xjvf gcc-4.8.5.tar.bz2 $ cd gcc-4.8.5 && ./contrib/download_prerequisites $ mkdir build-result && cd build-result $ ../configure --enable-checking=release --enable-languages=c,c++ --disable-multilib --disable-gnu-unique-object --prefix=/usr/local/gcc-4.8.5 $ make && sudo make install $ export PATH=/usr/local/gcc-4.8.5:$PATH

唯一需要注意的一點(diǎn)是選擇好安裝的目錄,并且將安裝目錄的內(nèi)容 export 到 PATH 中。

使用編譯得到的 g++,使用 v3 的編譯命令得到 main_v4 后,在運(yùn)行環(huán)境中成功執(zhí)行。

最后,我們可以直接 nm 比較一下 v3, v4:

$ nm main_v3 | grep "_ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE" 0000000000680cc0 u _ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE $ nm main_v4 | grep "_ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE" 000000000067dcc0 V _ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE

在 v4 中的符號(hào)類型發(fā)生了變化,V 代表的 weak object,這個(gè)類型可以兼容低版本的 ld。

小結(jié)

就我個(gè)人感受而言,鉆研二進(jìn)制兼容性更多是個(gè)熟悉和理解編譯工具以及操作系統(tǒng)所定義規(guī)則的過(guò)程,遠(yuǎn)不及設(shè)計(jì)和實(shí)現(xiàn)它們時(shí)的難度。但考慮到這個(gè)探索的過(guò)程也算挺折騰的,所以盡量把能夠總結(jié)的內(nèi)容通過(guò)本文進(jìn)行了整理,希望能讓讀者在后續(xù)做相關(guān)事情時(shí)少才踩些坑。

由于側(cè)重于介紹方法和分析的思路,文中所使用的應(yīng)用示例比較簡(jiǎn)單(只考慮了工具鏈依賴庫(kù)的范疇),后續(xù)有時(shí)間會(huì)補(bǔ)一篇針對(duì)較完善應(yīng)用的兼容性改造過(guò)程,敬請(qǐng)期待。

參考

    Creating portable Linux binaries

    此處的 libc.so 來(lái)源于 glibc,而非 Linux 歷史上的其他來(lái)源,對(duì)這段歷史感興趣的同學(xué)可以看一下 libc(7)

    舊版glibc兼容旅程 - CSDN博客

    SERVER-11641 undefined symbol: _ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE - MongoDB

    Re: --no-gnu-unique option to disable STB_GNU_UNIQUE

另外關(guān)于c++ Linux后臺(tái)服務(wù)器開(kāi)發(fā)的一些知識(shí)點(diǎn)分享:Linux,Nginx,MySQL,Redis,P2P,K8S,Docker,TCP/IP,協(xié)程,DPDK,webrtc,音視頻等等視頻。

喜歡的朋友可以后臺(tái)私信【1】獲取學(xué)習(xí)視頻

一、會(huì)寫(xiě)的字。

擱(耽擱)(擱置)(擱淺)

填(填補(bǔ))(填空)(填寫(xiě))

怨(怨恨)(埋怨)(怨言)

掀(掀起)(掀開(kāi))

唉(唉聲嘆氣)

裹(包裹)(裹腳)

魁(魁梧)(奪魁)

梧(梧桐)(魁梧)

淋(淋浴)(淋濕)(日曬雨淋)

撕(撕開(kāi))(撕扯)(撕碎)

霉(倒霉)(發(fā)霉)(青霉素)

慮(焦慮)(顧慮)(憂慮)

悠(悠久)(悠長(zhǎng))(悠閑)

儀(禮儀)(儀表)(儀式)

歉(道歉)(歉意)(歉疚)

溜(溜走)(溜冰)(滑溜)

嘿(嘿!)

割(割開(kāi))(收割)(割草)

二、辨字組詞。

三、詞語(yǔ)積累。

1.近義詞。

抱怨——埋怨 憂慮——焦慮

嚴(yán)肅——嚴(yán)厲 沮喪——懊喪

打擾——打攪 羞愧——慚愧

聲望——名望 著迷——入迷

悅耳——?jiǎng)勇?tīng) 果然——果真

的確——確實(shí) 叮囑——囑咐(吩咐)

心驚肉跳——膽戰(zhàn)心驚

自作自受——自食其果

自言自語(yǔ)——喃喃自語(yǔ)

流連忘返——戀戀不舍

忐忑不安——坐立不安

躡手躡腳——輕手輕腳

興高采烈——興致勃勃

無(wú)所不知——見(jiàn)多識(shí)廣

2.反義詞。

潮濕——干燥 嚴(yán)肅——活潑

偶然——必然 沮喪——得意

莊重——輕浮 羞愧——驕傲

慈祥——嚴(yán)厲 溫柔——粗暴

耐心——厭煩 熟悉——陌生

悅耳——刺耳

寒風(fēng)呼嘯——暖風(fēng)習(xí)習(xí)

躡手躡腳——大模大樣

流連忘返——?dú)w心似箭

忐忑不安——鎮(zhèn)定自若

興高采烈——無(wú)精打采

3.量詞積累。

一(張)帆 一(匹)馬

一(片)樹(shù)林 一(件)事情

一(束)陽(yáng)光 一(把)錘子

4.詞語(yǔ)搭配。

(洶涌澎湃)的海浪 (蒼白僵硬)的手

(清新)的海風(fēng) (流連忘返)的地方

(瘦削)的臉 (怒目圓睜)的臉

(茫然)的眼睛 (隆重)的儀式

(慈祥)的眼神 (唯一)的聽(tīng)眾

(溫柔)的嗓音 (躡手躡腳)地走出家門(mén)

(靜靜)地坐著/望著(耐心)地回答

(幸福)地歌唱

5.詞語(yǔ)歸類。

形容心神不安的成語(yǔ):

忐忑不安 惴惴不安

驚慌失措 六神無(wú)主

形容沒(méi)有變化的詞語(yǔ):

一如既往 一如往日

始終如一 自始至終

無(wú)~不~式成語(yǔ):

無(wú)所不知 無(wú)所不能

無(wú)所不在 無(wú)所不及

6.成語(yǔ)盤(pán)點(diǎn)。

心驚肉跳 忐忑不安

躡手躡腳 流連忘返

一如既往 溜之大吉

一動(dòng)不動(dòng) 盡心盡力

無(wú)所不知 十指連心

大吃一驚 身無(wú)分文

刻苦銘心 興高采烈

自作自受 不由分說(shuō)

自言自語(yǔ) 洶涌澎湃

四、日積月累。

輕諾必寡信。《老子》

民無(wú)信不立。《論語(yǔ)》

不精不誠(chéng),不能動(dòng)人。《莊子》

誠(chéng)者,天之道也;

誠(chéng)之者,人之道也。

《禮記》

有所期諾,纖毫必償;

有所期約,時(shí)刻不易。

《袁氏世范》

五、佳句欣賞。

1.屋外寒風(fēng)呼嘯,洶涌澎湃的海浪拍擊著海岸,濺起一陣陣?yán)嘶ā:I险鹬L(fēng)暴,外面又黑又冷,這間漁家的小屋里卻溫暖而舒適。地掃得干干凈凈,爐子里的火還沒(méi)有熄,食具在擱板上閃閃發(fā)亮。掛著白色帳子的床上,五個(gè)孩子正在海風(fēng)呼嘯聲中安靜地睡著。(環(huán)境描寫(xiě))《窮人》

2.桑娜沉思∶丈夫不顧惜身體,冒著寒冷和風(fēng)暴出去打魚(yú),她自己也從早到晚地干活,還只能勉強(qiáng)填飽肚子。孩子們沒(méi)有鞋穿,不論冬夏都光著腳跑來(lái)跑去;吃的是黑面包,菜只有魚(yú)。不過(guò),感謝上帝,孩子們都還健康。沒(méi)什么可抱怨的。(心理描寫(xiě))《窮人》

3.漁夫皺起眉,他的臉變得嚴(yán)肅、憂慮。“嗯,是個(gè)問(wèn)題!”他搔搔后腦勺說(shuō),“嗯,你看怎么辦?得把他們抱來(lái),同死人呆在一起怎么行!哦,我們,我們總能熬過(guò)去的!快去!別等他們醒來(lái)。”(動(dòng)作/語(yǔ)言/神態(tài)描寫(xiě))《窮人》

4.如果沒(méi)有他每天早上這寬厚的一笑,我就不會(huì)繼續(xù)白看他的書(shū),也就不會(huì)有那刻骨銘心的兩個(gè)耳光。(假設(shè))《別餓壞了那匹馬》

5.林子里靜極了。沙沙的足音,聽(tīng)起來(lái)像一曲悠悠的小令。(比喻/環(huán)境描寫(xiě))《唯一的聽(tīng)眾》

6.我感覺(jué)到背后有人,轉(zhuǎn)過(guò)身時(shí),嚇了一跳:一位極瘦極瘦的老婦人靜靜地坐在木椅上,平靜地望著我。(神態(tài)描寫(xiě))《唯一的聽(tīng)眾》

7.她慈祥的眼神平靜地望著我,像深深的潭水……《唯一的聽(tīng)眾》

8.后來(lái),拉小提琴成了我無(wú)法割舍的愛(ài)好,我能熟練地拉許多曲子。在各種文藝晚會(huì)上,我有機(jī)會(huì)面對(duì)成百上千的觀眾演奏小提琴曲。那時(shí),我總是不由得想起那位“耳聾”的老人,那清晨里我唯一的聽(tīng)眾……(點(diǎn)題)《唯一的聽(tīng)眾》

9.一天,我心愛(ài)的金絲雀突然死了。我非常難過(guò),心比被錘子砸了的手指還疼。《用心靈去傾聽(tīng)》

10.我相信蘇珊的話,我想可愛(ài)的小鳥(niǎo)的確到了另一個(gè)世界,一個(gè)比我們這個(gè)世界更為美麗的地方,幸福地歌唱。《用心靈去傾聽(tīng)》

六、課文主題。

《窮人》這篇文章通過(guò)記述漁夫和他的妻子桑娜收養(yǎng)鄰居西蒙的兩個(gè)孩子的故事,反映了窮人的悲慘生活和他們?cè)诶Э嘀袑幙勺约撼钥嘁惨獛椭鷦e人的高尚品質(zhì)。

《別餓壞了那匹馬》敘述了殘疾青年用善意的謊言讓“我”繼續(xù)看書(shū)的故事,贊揚(yáng)了殘疾青年不計(jì)一切得失、想方設(shè)法讓“我”看書(shū)的良苦用心,表達(dá)了“我”得知真相后的感激之情。

《唯一的聽(tīng)眾》記述了“我”在一位音樂(lè)教授的真誠(chéng)幫助下,由一個(gè)音樂(lè)“白癡”成長(zhǎng)為能上臺(tái)演奏的小提琴手的故事,贊揚(yáng)了老教授愛(ài)護(hù)、鼓勵(lì)年輕人成才的美德,表達(dá)了“我”對(duì)德高望重的老教授的敬佩、感激之情。

《用心靈去傾聽(tīng)》記述了“我”與問(wèn)訊處的工作人員蘇珊交往的過(guò)程,贊美了蘇珊用心靈傾聽(tīng)孩子的心聲、用愛(ài)心幫助孩子的善良品質(zhì),表達(dá)了“我”對(duì)蘇珊的深切的懷念之情。

七、單元鏈接與拓展。

關(guān)于自信的名言:

天生我材必有用。——李白

恢弘志士之氣,不宜妄自菲薄。——諸葛亮

有信心的人,可以化渺小為偉大,化平庸為神奇。——蕭伯納

一、給畫(huà)線字注音。(4分)

1.他悄悄地走到廚房,輕輕地掀( )起鍋蓋,好像一只偷吃的老鼠。

2.在神圣的教堂里,她一個(gè)人跪在神像前不停地抱怨( )生活的不公。

3.不知從何時(shí)開(kāi)始,他對(duì)手工藝品開(kāi)始著( )迷。

4.媽媽躡( )手躡腳地推開(kāi)了兒子的房門(mén),為他輕輕地蓋好了被子才慢慢地走了出來(lái)。

二、看拼音,寫(xiě)詞語(yǔ)。(8分)

kuí wǔ jiè yì

( ) ( )

quàn zǔ sī pò

( ) ( )

qīng tīng gē bǎn

( ) ( )

máng rán miǎn qiǎng

( ) ( )

三、根據(jù)語(yǔ)境,解釋劃線詞語(yǔ)的意思。(8分)

1.偷看書(shū)的時(shí)候,羞愧不已的我根本不敢回頭去看他那張瘦削的臉。

意思: ________________________

2.一拿到自己掙得的第一筆錢(qián),我泰然地走到精品屋,為媽媽挑選生日禮物。

意思: ________________________

3.通過(guò)討論,他們決定由參會(huì)人員中最有聲望的人去頒獎(jiǎng)典禮。

意思: ________________________

4.屋外寒風(fēng)呼嘯,洶涌澎湃的海浪拍擊著海岸,濺起一陣陣?yán)嘶ā?/strong>

意思: ________________________

四、先連線,再選詞填空。(6分)

心驚 自受

流連 肉跳

十指 忘返

自作 連心

1.驚險(xiǎn)的極限挑戰(zhàn)活動(dòng)令人( ),勇敢的挑戰(zhàn)者卻是鎮(zhèn)定自若。

2.即使孩子不小心磕破了皮,母親都會(huì)很心痛,畢竟( )。

五、判斷下列句子采用的描寫(xiě)方法,把正確的序號(hào)填在括號(hào)內(nèi)。(8分)

①環(huán)境描寫(xiě)②語(yǔ)言描寫(xiě)③心理描寫(xiě)④動(dòng)作描寫(xiě)

1.桑拿沉思:丈夫不顧惜身體,冒著寒冷和風(fēng)暴出去大魚(yú),她自己也從早到晚地干活,還只能勉強(qiáng)填飽肚子。 ( )

2.說(shuō)罷,父親奪過(guò)我手里的書(shū),匆匆地翻了一下,還給那個(gè)年輕人,拽著我走了。 ( )

3.我停下來(lái)時(shí),她總不忘說(shuō)上一句:“真不錯(cuò)。我的心已經(jīng)感受到了。謝謝你,小伙子。” ( )

4.村子里靜極了。沙沙的足音,聽(tīng)起來(lái)像一曲悠悠的小令。 ( )

六、把下列名句補(bǔ)充完整或填寫(xiě)出處。(8分)

1. _________,不能動(dòng)人。《莊子》

2.有所期諾,_________ ;

_________,_________ 。

《袁氏世范》

3.“民無(wú)信不立”出自_________。

4._________,天之道也;

_________, _________ 。

《禮記》

七、口語(yǔ)交際。(5分)

學(xué)校即將舉辦一次關(guān)于“講誠(chéng)信與善意的謊言是否相同”的辯論會(huì)。有些同學(xué)認(rèn)為“善意的謊言也是一種誠(chéng)信”,有的同學(xué)認(rèn)為“善意的謊言就是撒謊,是不誠(chéng)信的表現(xiàn)”,你支持哪一方的觀點(diǎn)呢?請(qǐng)說(shuō)說(shuō)你的觀點(diǎn)及理由。

觀點(diǎn): ______________________

理由: ______________________

八、閱讀天地。(23分)

(一)課內(nèi)閱讀。(9分)

《唯一的聽(tīng)眾》節(jié)選

一天早晨,我躡手躡腳地走出家門(mén),心里充滿了神圣感,仿佛要去干一件非常偉大的事情。林子里靜極了。沙沙的足音,聽(tīng)起來(lái)像一曲悠悠的小令。我在一棵樹(shù)下站好,莊重地架起小提琴,像舉行一個(gè)隆重的儀式,拉響了第一支曲子。但我很快又沮喪起來(lái),我覺(jué)得自己似乎又把鋸子帶到了樹(shù)林里。

我感覺(jué)到背后有人,轉(zhuǎn)過(guò)身時(shí),嚇了一跳:一位極瘦極瘦的老婦人靜靜地坐在木椅上,平靜地望著我。我的臉頓時(shí)燒起來(lái),心想,這么難聽(tīng)的聲音一定破壞了這林中的和諧,一定破壞了這位老人正獨(dú)享的幽靜。

1.“我躡手躡腳”的原因是什么?(2分)

2.請(qǐng)找出文中的比喻句用“______ ”畫(huà)出來(lái),并說(shuō)說(shuō)它的好處。(3分)

3.為什么“我”看到有個(gè)老人靜靜地坐在木椅上望著我,頓時(shí)感到臉燒?(4分)

(二)課外閱讀。(14分)

父親的愛(ài)

①爹不懂得怎樣表達(dá)愛(ài),使我們一家人融洽相處的是我媽。他只是每天上班下班,而媽則把我們做過(guò)的錯(cuò)事開(kāi)列清單,然后由他來(lái)責(zé)罵我們。

②有次我偷了塊糖果,他要我把它他回去,告訴賣(mài)糖的說(shuō)是我偷的,說(shuō)我愿意替他拆箱卸貨作為賠償。但媽媽卻明白我只是個(gè)孩子。

③我在運(yùn)動(dòng)場(chǎng)打秋千跌斷了腿,在前往醫(yī)院途中一直抱著我的,是我媽。爹把汽車(chē)停在急癥室門(mén)口,他們叫他駛開(kāi),說(shuō)那空位置是留給緊急車(chē)輛停放的。爹聽(tīng)了便叫嚷道:“你以為這是什么車(chē)?旅游車(chē)?”

④在我的生日會(huì)上,爹總是顯得有點(diǎn)不太相稱。他只是忙于吹氣球,布置餐桌,做雜務(wù)。把插著蠟燭的蛋糕推過(guò)來(lái)讓我吹的是我媽。

⑤我翻閱照相冊(cè)時(shí),人們總是問(wèn):“你爸爸是什么樣子的?”天曉得!他老是忙著替別人拍照,媽和我笑容可掬地一起拍的照片,多得不可勝數(shù)。

⑥我記得媽媽有一次叫他教我騎自行車(chē)。我叫他別放手,但他卻說(shuō)是應(yīng)該放手的時(shí)候了,我摔到這后,媽跑過(guò)來(lái)扶我,爸卻揮手要她走開(kāi)。我當(dāng)時(shí)生氣極了,決心要給他點(diǎn)顏色看。于是我馬上再爬上自行車(chē),而且自己騎給他看,他只是微笑。

⑦我念大學(xué)時(shí),所有的家信都是媽寫(xiě)的。他除了寄予支票以外,還寄過(guò)一封短柬給我,說(shuō)因?yàn)槲覜](méi)有在草坪上踢足球了,所以他的草坪長(zhǎng)得很美。

⑧每次我打電話回家,他似乎都想跟我說(shuō)話,但結(jié)果總是說(shuō):“我叫你媽來(lái)聽(tīng)。”

⑨我結(jié)婚時(shí),掉眼淚的是我媽。他只是大聲擤了一下鼻子,便走出房間。

⑩我從小到大都聽(tīng)他說(shuō):“你到哪里去了?什么時(shí)候回家?汽車(chē)有沒(méi)有汽油?不,不準(zhǔn)去。”爹不知道怎樣表達(dá)我。除非……

1.哪一句話是本文的中心句?用原文回答。(2分)

2.用簡(jiǎn)短的話概括本文的主要內(nèi)容?(3分)

3.請(qǐng)寫(xiě)出第六段最后一句話中“微笑”的含義。(4分)

4.文章最后一段的作用是什么?(5分)

九、作文。(30分)

“愛(ài)”是人生永恒的主題,生活中,有關(guān)愛(ài)你的家人,有你關(guān)愛(ài)的小動(dòng)物,也有陌生人對(duì)你的幫助以及你對(duì)陌生人的幫助。我們并不缺少愛(ài),而是缺少真正地體會(huì)愛(ài)。回憶一下,在你的周?chē)袥](méi)有發(fā)生哪些讓你記憶深刻的事情能夠體現(xiàn)“愛(ài)”。以“關(guān)愛(ài)”為話題,寫(xiě)一篇作文,題目自擬。

要求:寫(xiě)清事情的發(fā)展過(guò)程;注意人物的語(yǔ)言、動(dòng)作、心理活動(dòng)等;不少于450字。

參考答案

一、xiān yuàn zháo niè

二、魁梧 介意 勸阻 撕破 傾聽(tīng) 擱板 茫然 勉強(qiáng)

三、1.形容身體或臉很瘦。

2.形容心情十分安定。

3.為眾人所仰望的名聲。

4.文中形容海風(fēng)發(fā)出高而長(zhǎng)的聲音,說(shuō)明寒風(fēng)猛烈。

五、③④②①

六、不精不誠(chéng)

纖毫必償 有所期約,時(shí)刻不易

《論語(yǔ)》

誠(chéng)者 誠(chéng)之者,人之道也。

七、我贊成善意的謊言也是一種誠(chéng)信。

謊言是善意的,說(shuō)明是為了保護(hù)一些人不讓他們受到傷害,所以這種做法是值得肯定。因此肯定的做法是值得提倡的,所以我認(rèn)為“善意的謊言也是一種誠(chéng)信。”

八、(一)

1.“我”害怕驚動(dòng)家人,發(fā)現(xiàn)自己去練琴。

2.沙沙的腳步聲,聽(tīng)起來(lái)像一曲悠悠的小令。好處:“沙沙的足音”比喻成了“一曲悠悠的小令”,形象地說(shuō)明“我”對(duì)拉好琴重新找回了自信。

3.因?yàn)椤拔摇钡那偌疾缓茫幌M腥寺?tīng)見(jiàn)自己拉琴,卻被老人聽(tīng)見(jiàn)了,讓“我”再次失去了自信。

(二)

1.爹不懂得怎樣表達(dá)愛(ài),使我們一家人融洽相處的是我媽。

2.通過(guò)列舉了各種種種事實(shí),來(lái)表達(dá)父親對(duì)“我”的愛(ài)。

3.父親對(duì)“我”學(xué)會(huì)了自行車(chē)感到高興的笑;為我面對(duì)失敗,能夠有再次嘗試的勇氣而感到驕傲的笑。

4.用疑問(wèn)的方式總結(jié)全文,概括中心,告訴讀者父親不同方式來(lái)表達(dá)對(duì)“我”的愛(ài)。

九、作文(略)。