Невидимый SIGSEGV на Linux, который не происходит на Windows? - PullRequest
1 голос
/ 05 ноября 2011

INTRO

У меня есть TCP / HTTP-сервер, который поддерживает плагины в форме общих библиотек (DLL и .so). Он имеет make и .sln систему сборки файлов через premake . Когда я запускаю свое приложение, я передаю ему файл конфигурации, подобный этому, с описанием того, какой библиотечный сервер будет использовать в качестве плагинов и какие аргументы он должен передать им. Некоторое время у меня было 2 плагина, и все работало просто отлично. и даже сейчас работает просто отлично, если я передаю свои файлы конфигурации сервера fidiles this . Но теперь у меня есть новый плагин, который я разрабатываю, и поэтому новый файл конфигурации .

SETUP

Шаги, необходимые для настройки моего сервера в Linux, просты и понятны

  • скачать скрипт сборки (с здесь как описано здесь )
  • ./cloud_server_net_setup.sh, суперпользователь не требуется, требуется curl, make и g ++ В обычном случае (это не разработка, это достаточно - он получит поддержку, а другие библиотеки, которые ему нужны, будут помещены в локальную папку, он соберет их все, соберет сервер в форме выпуска)
  • теперь вы можете перейти на cloud_server/install-dir/
  • звонок export LD_LIBRARY_PATH=./:./lib_boost
  • и запустить наш сервер ./CloudServer

Но нам нужна отладочная версия, поэтому после вызова скрипта мы

  • cd cloud_server/CloudServer/projects/linux-gmake/
  • make
  • cd bin/debug
  • export LD_LIBRARY_PATH=./:(place from where we called our script)/cloud_server/install-dir/lib_boost

ПРОБЛЕМА

  • и теперь, наконец, мы можем вызвать GDB.

Так мы называем это. и вот что мы видим:

 gdb ./CloudServer

GNU gdb (GDB) 7.0.1-debian
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/ole_jak/cloud_server/CloudServer/projects/linux-gmake/bin/debug/CloudServer...done.
(gdb) r
Starting program: /home/ole_jak/cloud_server/CloudServer/projects/linux-gmake/bin/debug/CloudServer
[Thread debugging using libthread_db enabled]
Cloud Server v0.5
Copyright (c) 2011 Cloud Forever. All rights reserved.

Type 'help' to see help messages.
Config file path: config.xml
[New Thread 0x7ffff5967700 (LWP 11516)]
[New Thread 0x7ffff5166700 (LWP 11517)]
[New Thread 0x7ffff4965700 (LWP 11518)]
[New Thread 0x7ffff4164700 (LWP 11519)]
[New Thread 0x7ffff3963700 (LWP 11520)]
[New Thread 0x7ffff3162700 (LWP 11521)]
[New Thread 0x7ffff2961700 (LWP 11522)]
[New Thread 0x7ffff2160700 (LWP 11523)]
[New Thread 0x7ffff195f700 (LWP 11524)]
[New Thread 0x7ffff115e700 (LWP 11525)]
[New Thread 0x7ffff095d700 (LWP 11526)]
[New Thread 0x7fffebfff700 (LWP 11527)]
[New Thread 0x7fffeb7fe700 (LWP 11528)]
[New Thread 0x7fffeaffd700 (LWP 11529)]
[New Thread 0x7fffea7fc700 (LWP 11530)]
[New Thread 0x7fffe9ffb700 (LWP 11531)]
Library libFileService.so opened.
[New Thread 0x7fffe953c700 (LWP 11532)]
Library libUsersFilesService.so opened.

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) x/i $pc
0x0:    Cannot access memory at address 0x0

Я - Linux nube, и все, что я знаю о сбое в сегментации, я знаю из wikipedia , но я знаю еще одну вещь о моем сервере и об этой новой службе, которую я создаю - она ​​компилируется и работает в Windows без ошибки вообще (решения VS2008, 2010 могут быть созданы из одного и того же сценария предварительного создания).

Так что мне интересно, как и где в этих 2 файлах .cpp и .h я создал ошибку, которая не отображается в Windows, а также так драматично отображается в Linux? И это поправимо, или видно на свежий глаз?

UPDATE: Выход Valgrind

ole_jak@dspproc:~/cloud_server/CloudServer/projects/linux-gmake/bin/debug$ valgrind ./CloudServer
==11682== Memcheck, a memory error detector
==11682== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==11682== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==11682== Command: ./CloudServer
==11682==
Cloud Server v0.5
Copyright (c) 2011 Cloud Forever. All rights reserved.

Type 'help' to see help messages.
Config file path: config.xml
Library libFileService.so opened.
Library libUsersFilesService.so opened.
==11682== Jump to the invalid address stated on the next line
==11682==    at 0x0: ???
==11682==    by 0x4D49BE: sqlite3_free (sqlite3.c:18155)
==11682==    by 0x102242D5: sqlite3OsInit (sqlite3.c:14162)
==11682==    by 0x1029EB28: sqlite3_initialize (sqlite3.c:107299)
==11682==    by 0x102A159F: openDatabase (sqlite3.c:108909)
==11682==    by 0x102A1B29: sqlite3_open (sqlite3.c:109156)
==11682==    by 0x1021CAB0: sqlite3pp::database::connect(char const*) (sqlite3pp.cpp:89)
==11682==    by 0x1021C6E3: sqlite3pp::database::database(char const*) (sqlite3pp.cpp:74)
==11682==    by 0x1020DDDF: users_files_service::create_files_table(std::string) (users_files_service.cpp:171)
==11682==    by 0x1020BAFC: users_files_service::apply_config(boost::shared_ptr<boost::property_tree::basic_ptree<std::string, std::string, std::less<std::string> > >) (users_files_service.cpp:38)
==11682==    by 0x4B5432: server_utils::parse_config_services(boost::property_tree::basic_ptree<std::string, std::string, std::less<std::string> >) (server_utils.cpp:156)
==11682==    by 0x4B6436: server_utils::parse_config(boost::property_tree::basic_ptree<std::string, std::string, std::less<std::string> >) (server_utils.cpp:208)
==11682==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==11682==
==11682==
==11682== Process terminating with default action of signal 11 (SIGSEGV)
==11682==  Bad permissions for mapped region at address 0x0
==11682==    at 0x0: ???
==11682==    by 0x4D49BE: sqlite3_free (sqlite3.c:18155)
==11682==    by 0x102242D5: sqlite3OsInit (sqlite3.c:14162)
==11682==    by 0x1029EB28: sqlite3_initialize (sqlite3.c:107299)
==11682==    by 0x102A159F: openDatabase (sqlite3.c:108909)
==11682==    by 0x102A1B29: sqlite3_open (sqlite3.c:109156)
==11682==    by 0x1021CAB0: sqlite3pp::database::connect(char const*) (sqlite3pp.cpp:89)
==11682==    by 0x1021C6E3: sqlite3pp::database::database(char const*) (sqlite3pp.cpp:74)
==11682==    by 0x1020DDDF: users_files_service::create_files_table(std::string) (users_files_service.cpp:171)
==11682==    by 0x1020BAFC: users_files_service::apply_config(boost::shared_ptr<boost::property_tree::basic_ptree<std::string, std::string, std::less<std::string> > >) (users_files_service.cpp:38)
==11682==    by 0x4B5432: server_utils::parse_config_services(boost::property_tree::basic_ptree<std::string, std::string, std::less<std::string> >) (server_utils.cpp:156)
==11682==    by 0x4B6436: server_utils::parse_config(boost::property_tree::basic_ptree<std::string, std::string, std::less<std::string> >) (server_utils.cpp:208)
==11682==
==11682== HEAP SUMMARY:
==11682==     in use at exit: 124,050 bytes in 1,083 blocks
==11682==   total heap usage: 1,814 allocs, 731 frees, 183,517 bytes allocated
==11682==
==11682== LEAK SUMMARY:
==11682==    definitely lost: 0 bytes in 0 blocks
==11682==    indirectly lost: 0 bytes in 0 blocks
==11682==      possibly lost: 46,248 bytes in 799 blocks
==11682==    still reachable: 77,802 bytes in 284 blocks
==11682==         suppressed: 0 bytes in 0 blocks
==11682== Rerun with --leak-check=full to see details of leaked memory
==11682==
==11682== For counts of detected and suppressed errors, rerun with: -v
==11682== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)
Убито
ole_jak@dspproc:~/cloud_server/CloudServer/projects/linux-gmake/bin/debug$

Ответы [ 2 ]

2 голосов
/ 06 ноября 2011

Это противный один.Я не уверен в точной основной причине, но это, кажется, проблема, связанная с многопоточностью.Непосредственной причиной проблемы является то, что указатель функции sqlite3Config.m.xSize равен NULL в том месте и в тот момент, когда произошла ошибка.

Предполагается, что этот указатель инициализируется, чтобы указывать на правильную функцию в первый раз, когдаsqlite3_initialize() вызывается, что обычно происходит при первом открытии файла базы данных SQLite.Устанавливая точки останова и точки наблюдения в GDB, я смог убедиться, что указатель успешно установлен, но во время ошибки сегментации его значение равно NULL.

Это может означать одно из двух:

  • Новое значение указателя не распространяется должным образом на все потоки.SQLite3 должен быть поточно-ориентированным, но потоки могут быть неприятными небольшими ошибками ...

  • Что-то сбрасывает указатель после его инициализации.Я считал это крайне маловероятным, поскольку структура sqlite3Config обычно не модифицируется после инициализации.

Я выполнил простой тест, который, кстати, можно использовать как временный обходной путь: я добавил явный обходной путь:вызов sqite3_initialize() в качестве первого оператора в main(), позволяющий выполнить его до запуска любых потоков.В результате ошибка сегментации ушла, и я получил приглашение оболочки для вашего сервера, которое указывает на первый из двух вариантов.Обратите внимание, что в лучшем случае это обходной путь, так как sqite3_initialize() не должен вызываться явно.Основная причина проблемы все еще может присутствовать и заявить о себе иначе - или, что еще хуже, она может сломать вещи тонкими, но трудными для обнаружения способами.

Поскольку SQLite3 должен быть потоком-safe (а исходный код функции sqlite3_initialize() кажется правильным в этом отношении), я не уверен, что происходит.Это может быть проблема с оболочкой sqlite3pp или с тем, как запускаются потоки.

0 голосов
/ 05 ноября 2011

вот мои предложения.

  1. отключить оптимизацию. Иногда оптимизации вызывают ошибки. используйте, например, -O0.
  2. удалите динамическую загрузку, попробуйте статически связать ваш код и посмотрите, не возникла ли проблема.
  3. уменьшить размер проблемы. Сделайте наименьшую возможную программу, которая может воспроизвести ошибку, а затем опубликуйте ее здесь.

спасибо, микрофон

...