1. 程式人生 > >關於#pragma pack(n)引發的一系列問題

關於#pragma pack(n)引發的一系列問題

[前提]
最近在寫新系統程式碼的時候, 因為引用了一個包含了如下內容的標頭檔案, 導致系統core的莫名奇妙, core在了打log的時候, std::string的析構上, 程式碼如下:

... ...
#pragma pack(1)

strcut XXX {
... ...
}

#pragma

所有包含了這一標頭檔案的cpp中的類, 打log即掛(後面實驗, 要core可以很多種辦法).
後來發現是因為我編譯加了 -O2, 不加的話不會掛.
這裡請注意, #pragma pack(1)並沒有以#pragma pack()結束.

[原因分析]
GDB檢查了一下core的原因, 是因為std::string在#pragma後面, 而上面那個寫法比較坑, 並沒有以#pragma pack()結束, 導致後面的string全部都按1位元組對齊, 會導致一些計算長度上的誤差, 在-O2編譯的時候, 會出現一系列的 malloc/free 錯誤.
這裡貼上core資訊:

0x00000000006224c9 in __gnu_cxx::__exchange_and_add (__val=-1, __mem=0xb1491800007ff7) at /usr/include/c++/4.9/ext/atomicity.h:49
49    { return __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL); }
(gdb) bt
#0  0x00000000006224c9 in __gnu_cxx::__exchange_and_add (__val=-1, __mem=0xb1491800007ff7) at /usr/include/c++/4.9/ext/atomicity.h:49
#1 __gnu_cxx::__exchange_and_add_dispatch (__val=-1, __mem=0xb1491800007ff7) at /usr/include/c++/4.9/ext/atomicity.h:82 #2 std::string::_Rep::_M_dispose (__a=..., this=0xb1491800007fe7) at /usr/include/c++/4.9/bits/basic_string.h:246 #3 std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string (this
=0x7fffffffcd4c, __in_chrg=<optimized out>) at /usr/include/c++/4.9/bits/basic_string.h:546 #4 log::LogRecord::~LogRecord (this=0x7fffffffcd20, __in_chrg=<optimized out>) at ....../LogRecord.h:27 #5 pb_monitor::Init (this=this@entry=0x7fffffffd580, config=...) at ....../pb_monitor.cpp:17 #6 0x0000000000577443 in main (argc=<optimized out>, argv=<optimized out>) at ....../main.cpp:9

[樣例]
可以自己寫個小程式復現一下便知:

test.h

#ifndef TEST_H_
#define TEST_H_

#pragma pack(1)

#endif /* TEST_H_ */

test.cc

#include "test.h"
#include <iostream>
#include <string>

using namespace std;

int main() {
  std::string name("1234567890.txt");
  std::string::size_type pos = name.rfind(".");
  std::string filename = name.substr(0, pos);
  cout<< filename << endl;
  return 0;
}

g++ -o test -O2 ./test.cc

ALLEN.L.R
2017/09/05