首页 > 代码库 > 位域结构体多线程访问出错的问题分析

位域结构体多线程访问出错的问题分析

  位域结构体能节省一些内存空间,但是使用不当会产生race conditions,导致程序异常,下面简要分析错误产生的原因和解决方案。

 

  首先定义一个简单的bit field结构体。

+struct bit_filed {+       unsigned a : 1;+       unsigned b : 1;+       unsigned c : 1;+       unsigned d : 1;+       unsigned e : 1;+       unsigned f : 1;+       unsigned g : 1;+       unsigned h : 1;+} val;+++int test_bitfield1(void)+{+       val.a = 1;+       return 0;+}++int test_bitfield2(void)+{+       val.b = 1;+       return 0;+}

 

   然后反汇编

ffffffc0005421e8 <test_bitfield1>:ffffffc0005421e8:       f0000fa1        adrp    x1, ffffffc000739000 <__hyp_idmap_text_end+0x4800>ffffffc0005421ec:       f9426821        ldr     x1, [x1,#1232]ffffffc0005421f0:       52800000        mov     w0, #0x0                        // #0ffffffc0005421f4:       39400022        ldrb    w2, [x1]ffffffc0005421f8:       32000042        orr     w2, w2, #0x1ffffffc0005421fc:       39000022        strb    w2, [x1]ffffffc000542200:       d65f03c0        ret ffffffc000542204 <test_bitfield2>:ffffffc000542204:       f0000fa1        adrp    x1, ffffffc000739000 <__hyp_idmap_text_end+0x4800>ffffffc000542208:       f9426821        ldr     x1, [x1,#1232]ffffffc00054220c:       52800000        mov     w0, #0x0                        // #0ffffffc000542210:       39400022        ldrb    w2, [x1]ffffffc000542214:       321f0042        orr     w2, w2, #0x2ffffffc000542218:       39000022        strb    w2, [x1]ffffffc00054221c:       d65f03c0        ret

  可以看到,这种情况下最小访存单元是一个byte,在上面标黄的指令中会从内存读取一个副本,如果test_bitfield1在执行黄色指令后被test_bitfield2强行插入,test_bitfield2执行完毕后test_bitfield1继续执行,

在这种情况下test_bitfield2所做的修改会被丢弃。

  所以平时如果需要用到bit filed struct, 需要注意:

  1. 不同位域变量是不是在一个storage unit(可以通过反汇编查看)里面

  2. 有没有被并发访问的可能。

 

  下面这篇文章分析了这个问题并给出了几种解决方案:

  https://www.securecoding.cert.org/confluence/display/seccode/CON32-C.+Prevent+data+races+when+accessing+bit-fields+from+multiple+threads

  1. One approach for preventing data races in concurrent programming is to use a mutex
  2. Another approach is to insert a non-bit-field member between any two bit-fields to ensure that each bit-field is the only one accessed within its storage unit.
  3. Use distinct non-bit-field members of a structure

 

位域结构体多线程访问出错的问题分析