背景

android模擬器運行於virtualbox中,而virtualbox運行於x86架構的pc端,所以android及其Linux內核都編譯成x86架構。當virtualbox的vt未開啟的情況下android系統會出現各種問題,如arm庫游戲不能運行,桌面平凡掛死重啟。通過查看日志,都奔潰在了#00 pc 000183c6 /system/lib/libc.so (__get_thread+6)這個點。關於此點的日志分析過程請查看本人的另一篇文章的分析: Linux系統調用__get_thread獲取TLS失敗導致應用程序奔潰.

問題

在android內核為3.10時選擇CONFIG_CC_STACKPROTECTOR=y(開啟內核棧保護功能),在x86架構下能正常編譯解決vt下桌面重復掛死、arm庫游戲不能玩的問題。但是如果升級android內核為3.18,內核開啟棧保護功能時,交叉編譯x86架構下的linux內核就會出現編譯錯誤。具體看如下開啟內核配置和出錯日志:

開啟3.18棧保護的內核配置選項如下:@@ -41,7 +41,6 @@ CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y

CONFIG_HAVE_INTEL_TXT=y

CONFIG_X86_32_SMP=y

CONFIG_X86_HT=y

-CONFIG_X86_32_LAZY_GS=y

CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-ecx -fcall-saved-edx"

CONFIG_ARCH_SUPPORTS_UPROBES=y

CONFIG_FIX_EARLYCON_MEM=y

@@ -249,10 +248,10 @@ CONFIG_HAVE_CMPXCHG_DOUBLE=y

CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y

CONFIG_HAVE_ARCH_SECCOMP_FILTER=y

CONFIG_HAVE_CC_STACKPROTECTOR=y

-# CONFIG_CC_STACKPROTECTOR is not set

-CONFIG_CC_STACKPROTECTOR_NONE=y

+CONFIG_CC_STACKPROTECTOR=y

+# CONFIG_CC_STACKPROTECTOR_NONE is not set

# CONFIG_CC_STACKPROTECTOR_REGULAR is not set

-# CONFIG_CC_STACKPROTECTOR_STRONG is not set

+CONFIG_CC_STACKPROTECTOR_STRONG=y

CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES=y

CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y

CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y

開啟3.18內核棧保護配置后內核編譯x86架構錯誤如下:CHK include/generated/compile.h

UPD include/generated/compile.h

CC init/version.o

LD init/built-in.o

android-4.4.4/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.6/bin/i686-linux-android-ld: init/built-in.o: in function do_one_initcall:init_task.c(.text+0x7f): error: undefined reference to '__stack_chk_guard'

android-4.4.4/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.6/bin/i686-linux-android-ld: init/built-in.o: in function do_one_initcall:init_task.c(.text+0x1c6): error: undefined reference to '__stack_chk_guard'

android-4.4.4/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.6/bin/i686-linux-android-ld: init/built-in.o: in function name_to_dev_t:init_task.c(.text+0x261): error: undefined reference to '__stack_chk_guard'

android-4.4.4/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.6/bin/i686-linux-android-ld: init/built-in.o: in function name_to_dev_t:init_task.c(.text+0x517): error: undefined reference to '__stack_chk_guard'

make: *** [vmlinux] Error 1

arch/x86/Makefile:116: stack-protector enabled but compiler support broken

分析解決

上述error: undefined reference to '__stack_chk_guard'錯誤通過各種google也沒有找到正解,有的說是gcc需要4.9及以上,然而用交叉編譯工具4.9也不行。還查看了android源碼關於stack protector的相關修復,都沒有啥卵用。最后通過查看__stack_chk_guard字段發現,x86架構沒有定義此字段,而sh,arm,mips等架構確定義了。在窮途末路時只能自己動手依葫蘆畫瓢,期待有所進展。如下patch為本人添加,不僅能解決編譯錯誤,還確實解決了vt未開啟時,virtualbox下運行android鏡像出現的各種問題。

Linux編譯x86架構時__stack_chk_guard未定義錯誤的修復patchdiff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h

index 6a99859..3e2d812 100644

--- a/arch/x86/include/asm/stackprotector.h

+++ b/arch/x86/include/asm/stackprotector.h

@@ -41,6 +41,10 @@

#include

#include

+#if (defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP))

+extern unsigned long __stack_chk_guard;

+#endif

+

/*

* 24 byte read-only segment initializer for stack canary. Linker

* can't handle the address bit shifting. Address will be set in

@@ -79,6 +83,10 @@ static __always_inline void boot_init_stack_canary(void)

#else

this_cpu_write(stack_canary.canary, canary);

#endif

+

+#if (defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP))

+ __stack_chk_guard = current->stack_canary;

+#endif

}

static inline void setup_stack_canary_segment(int cpu)

diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c

index 4eb204c..5ad8ab2 100644

--- a/arch/x86/kernel/process.c

+++ b/arch/x86/kernel/process.c

@@ -29,6 +29,12 @@

#include

#include

+

+#if (defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP))

+ unsigned long __stack_chk_guard __read_mostly;

+/* 配置打開SMP時,會出現此__stack_chk_guard變量重復定義問題,所有只能在無SMP下生效 */

+//static DEFINE_PER_CPU(unsigned long,__stack_chk_guard) __read_mostly;

+EXPORT_SYMBOL(__stack_chk_guard);

+#endif

+

/*

* per-CPU TSS segments. Threads are completely 'soft' on Linux,

* no more per-task TSS's. The TSS size is kept cacheline-aligned

diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c

index 8f3ebfe..f027d25 100644

--- a/arch/x86/kernel/process_32.c

+++ b/arch/x86/kernel/process_32.c

@@ -39,6 +39,11 @@

#include

#include

#include

+

+#if (defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP))

+#include

+#endif

+

#include

#include

#include

@@ -249,6 +254,11 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)

*next = &next_p->thread;

int cpu = smp_processor_id();

struct tss_struct *tss = &per_cpu(init_tss, cpu);

+

+ #if (defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP))

+ __stack_chk_guard = next_p->stack_canary;

+ #endif

+

fpu_switch_t fpu;

/* never put a printk in __switch_to... printk() calls wake_up*() indirectly */

為啥內核能正常選擇打開棧保護功能但卻無法編譯通過呢,后面想了想,可能有如下原因:

一是godlfish內核主要對移動手機設備使用的內核,手機一般使用的是arm芯片,對於x86架構官方關注的也許並不多。

二是默認此棧保護功能是關閉的,只有對運行穩定性有特殊需求的產品,如航天,太空類高穩定產品才需要考慮打開,打開后會稍微降低性能。

此patch應該是可以作為官網的patch來提交修復,福澤大眾的,但本人從來沒有提交過,限於水平有限,暫且記錄,以備后忘。

感謝

2017 …… ,卷起褲管跑,擼起袖子干!

linux 内核裁剪不当 死机,Linux編譯x86架構內核出現_stack_chk_guard未定義錯誤相关推荐

  1. Linux内核裁剪及编译

    Linux内核裁剪及编译可加载模块 一 Linux基础知识 linux内核组要由五个子系统组成: 进程调度 内存管理 文件系统 网络接口 进程间通信 Linux源码目录 arch    目录中包含于体 ...

  2. linux 内核裁剪的具体过程和方法,Linux内核裁剪的具体过程和方法

    Linux内核裁剪的具体过程和方法 这是我前段时间自己整的一份,内核功能: 能够完成系统的基本功能,上网,收发邮件等,支持xwindows图形界面. 在menuconfig中配置: 详细介绍内核配置选 ...

  3. 当运行 Linux 内核的机器死机时...

    [CSDN 编者按]事件陷入死地无可挽救之际,可能会有人选择不了了之,有人选择就此放弃--但换个思路想一想,既然都无可挽回了,那干嘛不试试弄点有价值的信息回来? 作者 | dog250  责编 | 张 ...

  4. 第三十九天:linux内核裁剪

    培训的第四阶段:通过编写驱动,从应用层,内核层,再到底层硬件之间的关系.明白内核驱动的意义.现在开始才是重头戏,前面的都是铺垫. 正式编写驱动前,要先了解linux内核代码的组成.linux主要是由五 ...

  5. [转载]基于ARM的linux内核裁剪与移植

    基于ARM的linux内核裁剪与移植 http://bbs.elecfans.com/forum.php?mod=viewthread&tid=185020  wutaimin( 楼主 ) 2 ...

  6. ARM在嵌入式linux内核裁剪与移植的应用

    微处理器用一片或少数几片大规模集成电路组成的中央处理器.这些电路执行控制部件和算术逻辑部件的功能.微处理器与传统的中央处理器相比,具有体积小,重量轻和容易模块化等优点.微处理器的基本组成部分有:寄存器 ...

  7. linux 脚本裁剪内核,Linux 内核裁剪的自动化方法

    Linux 内核裁剪的自动化方法 随着广泛地获得使用并被移植到不同的平台,Linux 内核源代码正在越来越大,比如, Linux 2.6.28 中, 文件数有 25282 个,大小有350M. 对于某 ...

  8. Linux内核态之间进程通信,Linux 系统内核空间与用户空间通信的实现与分析[转载]...

    [https://www.ibm.com/developerworks/cn/linux/l-netlink/index.html] 多数的 Linux 内核态程序都需要和用户空间的进程交换数据,但 ...

  9. 移植linux内核-映像文件,移植Linux内核-映像文件

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明 http://tigerwang202.blogbus.com/logs/43927976.html 首先从Blackfin uCli ...

最新文章

  1. android sqlite用户注册代码,用户名和密码登录android登录sqlite
  2. 微软对学生免费提供Visual Studio等开发软件(包括中国)
  3. 解决Eclipse 启动后总是Building WorkSpace(sleeping)
  4. lazadashopee代运营服务有哪些,能帮商家解决哪些问题?
  5. 小程序开发学习(5)---实现天气预报小程序
  6. android 弹出框带标题栏,Android开发靠标题栏的弹框
  7. A/B HDU - 1576 (逆元或拓展欧几里得或数学公式)多解法求大数结果
  8. C# 线程手册 第三章 使用线程 Monitor.TryEnter()
  9. Git 提交报错,账户和密码错误 和 git add/git commit 文件太大太多
  10. python常问问题_Python新手在作用域方面经常容易碰到的问题
  11. Python数学建模入门【1】
  12. Eclipse语言包及ADT安装教程
  13. iOS 玩转微信——下拉小程序
  14. 【Records】部分功能模块介绍
  15. 命令与征服4 You might have build the wrong LOD level 错误
  16. photoshop cs6基础学习
  17. java方法的通用格式,【学习笔记】使用Java读取、写入Excel全版本(包含xls、xslx格式)通用方法及代码展示(POI)...
  18. matlab画箱型图均值方差,Matlab 绘制箱线图
  19. php 设置数字键盘,window_win10启动时如何设置默认打开小键盘数字输入切换键?,win10作为微软的一次重大变革 - phpStudy...
  20. 7-38 实验7_3_奇数偶数 (100 分)

热门文章

  1. 解决PendingIntent传递参数为空的问题
  2. page.ClientScript.RegisterStartupScript
  3. ListView排序并隔色显示
  4. 抓取新浪的每日星座运势
  5. 3D模型格式解析(OBJ)
  6. insert和insertSelective区别
  7. Leetcode--16. 最接近的三数之和
  8. oracle怎么把整形,【用bbed工具对Oracle进行微整形】
  9. c语言商品货架管理_汽配仓库布局及管理
  10. C语言定义外部变量或函数使得另一个C文件可以调用