ATTR引發的編譯錯誤 原創

2022-03-08 13:16:11 字數 2252 閱讀 7493

有一天我編譯核心模組驅動的時候發現如下錯誤

linux kernel版本:4.1.15

error: negative width in bit-field '

'

**如下:

static

struct device_attribute sysfs_keypad_list =;

當我做這樣的修改後:

static

struct device_attribute sysfs_keypad_list =;

編譯就不報錯了

這樣讓我很是奇怪,接下來咱們跟入**一看究竟

首先我們看下__attr的實現:

繼續跟入,我們發現如下的演算法,顯而易見,此版本的核心對許可權做了乙個小小的演算法,如下演算法大家可以寫乙個簡單的c**進行解讀

當我傳入perms=0x666的時候,build_bug_on_zero(perms & 2) 這個會報錯,因為如下:

為什麼 build_bug_on_zero( (0x666) & 2 )會報錯呢?

我們可以寫這樣的**來驗證一下:

#include int

main()

;

return

0;

}

執行:

出現了同樣的錯誤,那麼我們應該明白了吧,gcc會在編譯的時候對位域的定義進行檢查,struct 這樣的定義編譯器會認為是錯誤的

那至於為什麼會列印這樣的錯誤呢?這就需要對編譯器進行了解了,也就是編譯器是如何檢查結構體位域的定義的,這塊我沒有深入研究過

如下引用一段話,摘自網上(

linux probably refuses to make module parameters world-writable for security reasons.

you should be able to use narrower permissions such ass_iwusr | s_iwgrp

通俗的理解就是核心希望這樣做的安全一點,減少其他組的寫許可權,體現在 build_bug_on_zero(perms & 2)這個設計上

那麼我們如何修改呢?

有如下兩種方式的思路給大家借鑑:

第一種:

這樣設計的思路是為了遵循作者的思想,保障安全(但__attr這個巨集的用法不同版本是有差別的在這塊,比如說3.6.5的版本是不會檢查這個許可權問題的)

static

struct device_attribute sysfs_keypad_list =;

第二種:

這樣設計的思路是因為搞驅動開發的相信大家都清楚,如果這個介面是我們曾經釋放出去的,開放了這樣的許可權

那麼我們後期開發的時候必須相容之前的介面設計,不能這樣隨意的更改許可權,因為如果你修改了,某個客戶之前有這樣子使用許可權的話,你改了許可權後,他可能就用不了了,

因此我們可以做如下處理,思路就是我們自己定義,不使用核心的設計

#undef __attr

#define __attr(_name, _mode, _show, _store) , \

.show =_show, \

.store =_store, \

}static

struct device_attribute sysfs_keypad_list =;

方法三:

#undef verify_octal_permissions

#define verify_octal_permissions(perms) (perms)

static device_attr(reg_value, 0666, zbh_reg_show, zbh_reg_store);

分析如上,如有描述不準確的地方還請告知,thanks

mk編譯錯誤

要在工程 中加乙個巨集去控制 在config.mk中定義這個巨集 enable it6263 1 在compile option.mk中根據這個值來定義巨集 ifeq enable it6263 1 cc opts denable it6263 1 else cc opts denable it62...

Greta 編譯錯誤

背景 greta2.6.4在vs2008編譯通過,在vs2013中,編譯出現以下錯誤 1 regexpr2.cpp 1 c users administrator desktop greta greta restack.h 56 error c2332 struct 缺少標記名 1 c users ...

c 編譯錯誤

一.變數未定義的引用 1.如果變數是類中的靜態成員,需要先在類外部初始化。否則會出現此種錯誤 二。標頭檔案包含了,卻報 zsp ipc proxy client.hh 8 1 錯誤 expected class name before endif 注意不能包含這些函式所在庫的標頭檔案。比如info ...