应用程序崩溃并发访问std :: string

时间:2014-03-07 18:08:57

标签: c++ string multithreading new-operator

我有一个多线程应用程序,我使用std :: map存储键值对。虽然我保持对使用互斥锁(pthread,因为不使用C ++ 11)的std :: map的访问以确保互斥,但是基于数据的密钥是在互斥块之外。这是因为我的密钥制作是在本地完成的,而不是共享数据。我有一个小的实用程序函数mkkey,它按值返回一个字符串,定义如下:

std::string mkkey(char *n1, char *n2, int d) {
  char buff[200];
  sprintf(buff, "%s:%s:%d", n1, n2, d);
  return buff;
}

mkkey的参数不是null并且是有效字符串,在大小限制内,所以我不超过缓冲区大小。但是,我遇到了崩溃,pstack核心显示如下: 一个帖子:

 --- called from signal handler with signal 10 (SIGBUS) ---
 00271340 allocate__t24__default_alloc_template2b0i0Ui (30, 30, 10, 2, 1, 0) + a4
 0015ec84 __nw__Q2t12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0_3RepUiUi (10, 20, 1, 2, 1, 1) + 14
 0015fa44 create__Q2t12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0_3RepUi (19, 19, 664e10, fc27b694, ffbff790, fffc00) + 24
 0016c71c replace__t12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0UiUiPCcUi (fc27b888, 0, ffffffff, fc27b038, 19, 80808080) + 114
 002af8c4 assign__t12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0PCcUi (fc27b888, fc27b038, 19, fc27b051, 1, 1) + 24
 0029b380 assign__t12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0PCc (fc27b888, fc27b038, 7fffffe6, 664e10, fc27b051, 7fffffe6) + 24
 00263600 __t12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0PCc (fc27b888, fc27b038, 7ffffc00, 664e10, fc27b895, 19) + 28
 0012caec mkKey__FRC8UserData (fc27b890, fc27b888, fc27b8a1, 0, ff000000, 80808080) + f4

和另一个主题:

-----------------  lwp# 7 / thread# 7  --------------------
 0025b148 data__Q2t12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0_3Rep (84f970, 4631bc, 1, 2, 1, 0) + 4
 001616c8 copy__Q2t12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0_3RepUiPCcUi (84f970, 0, fbe7b0c8, 19, ffbff790, fffc00) + 24
 0016c7a8 replace__t12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0UiUiPCcUi (fbe7b918, 0, ffffffff, fbe7b0c8, 19, 80808080) + 1a0
 002af8c4 assign__t12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0PCcUi (fbe7b918, fbe7b0c8, 19, fbe7b0e1, 1, 1) + 24
 0029b380 assign__t12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0PCc (fbe7b918, fbe7b0c8, 7fffffe6, 664e10, fbe7b0e1, 7fffffe6) + 24
 00263600 __t12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0PCc (fbe7b918, fbe7b0c8, 7ffffc00, 664e10, fbe7b925, 19) + 28
 0012caec mkKey__FRC8UserData (fbe7b920, fbe7b918, fbe7b931, 0, ff000000, 80808080) + f4

崩溃的线程似乎在SIGBUS上崩溃,通常表示访问无效地址。怎么可能出错?由于从mkkey返回值而形成的std :: string应该重新创建一个std :: string,但它显示alloc失败。它与std :: string有关吗?在使用少量数据进行调试时,我没有看到任何明显的问题,问题来自更大的数据量。堆大小是否会导致synamic分配失败?或者它是std :: string本身?我故意将mkkey保存在互斥锁之外,因为它是在本地完成而不是在共享数据上完成的。

1 个答案:

答案 0 :(得分:0)

这是堆损坏,可能有很多原因,这是程序中可能发生的最丑陋的错误。它有很多原因,没有必要列出它们。它足以让一小块有缺陷的代码覆盖其他内存,例如通过过度索引或通过编写悬空指针......

以下是调试堆损坏的一系列建议:How to debug heap corruption errors?

我自己通常使用特殊的分配器调试它们,并将(非常慢的)全内存一致性检查调用调用到我的程序中的特定位置,这样我有时可以长时间搜索我的腐败发生的位置