У меня есть сервер/клиентская система, которая хорошо работает на моих машинах. Но он сбрасывает ядра на одном из компьютеров пользователей (ОС: Centos 5). Поскольку у меня нет доступа к машине пользователя, поэтому я построил двоичный код режима отладки и попросил пользователя попробовать его. Крушение произошло снова после двух дней бега. И он отправил мне основной файл дампа. Загружая файл дампа ядра с помощью gdb, он показывает местоположение сбоя, но я не понимаю причину (извините, мой предыдущий опыт в основном связан с Windows. У меня нет большого опыта работы с Linux/gdb). Я хотел бы получить ваш вклад. Благодаря!gdb - определить причину ошибки сегментации
1./вар/Журнал/сообщения на компьютере пользователя показывает Segfault:
Jan 16 9:20:39 LPZ08945 ядра: LSYSTEM [4688]: на 0000000000000000 выдаёт ошибку сегментации рип 00000000080e6433 RSP 00000000f2afd4e0 error 4
Это сообщение указывает, что существует указатель segfault в указателе инструкции 80e6433 и указатель стека f2afd4e0. Похоже, что программа пытается читать/писать по адресу 0.
2. нагрузки основной файл дампа в GDB и показывает расположение аварии:
$ GDB LSYSTEM core.19009
ГНУ GDB (GDB) CentOS (7.0.1-45.el5.centos)
... (много линий выходов из GDB опущенных)
ядро был сгенерирован `./LSystem».
Программа завершена сигналом 11, Ошибка сегментации.
'# 0' 0x080e6433 в CLClient :: connectToServer (это = 0xf2afd898, Conn = 11) при liccomm/LClient.cpp: 214
214 тетсру ((символ *) & (a4.sin_addr), pHost -> h_addr, pHost-> h_length);
gdb говорит, что авария происходит на линии 214?
3. Информация о кадре. (В кадре # 0)
(GDB) Информация кадра
уровень стека 0, рамка на 0xf2afd7e0:
EIP = 0x80e6433 в CLClient :: connectToServer (liccomm/LClient.cpp: 214); сохранены EIP 0x80e6701
вызывается репера в 0xf2afd820
исходного языка C++.
список аргументов в 0xf2afd7d8, арг: это = 0xf2afd898, Conn = 11
Местные жители в 0xf2afd7d8, зр предыдущий кадр является 0xf2afd7e0
Сохраненные регистры:
EBX на 0xf2afd7cc, EBP в 0xf2afd7d8, еси в 0xf2afd7d0, ЭОД в 0xf2afd7d4, EIP в 0xf2afd7dc
кадр в f2afd7e0, почему это отличается от RSP из части 1, которая f2afd4e0? Я предполагаю, что пользователь предоставил мне несоответствующий файл дампа ядра (чей pid - 19009) и/var/log/messages file (который указывает на pid 4688).
4. Источник
(GDB) список +
209
210 //pHost is declared as struct hostent* and 'pHost = gethostbyname(serverAddress);'
211 memset(&a4, 0, sizeof(a4));
212 a4.sin_family = AF_INET;
213 a4.sin_port = htons(nPort);
214 memcpy((char *) & (a4.sin_addr), pHost->h_addr, pHost->h_length);
215
216 aalen = sizeof(a4);
217 aa = (struct sockaddr *)&a4;
Я не мог видеть ничего плохого в линии 214. И эта часть кода много раз должен побежал во время выполнения 2 дня.
5. Переменные
Так как GDB показано, что линия 214 был виновником. Я печатал все.
memcpy((char *) & (a4.sin_addr), pHost->h_addr, pHost->h_length);
(GDB) печати a4.sin_addr
$ 1 = {s_addr = 0}
(GDB) печати & (a4.sin_addr)
$ 2 = (in_addr *) 0xf2afd794
(GDB) печати pHost-> h_addr_list [0]
$ 3 = 0xa24af30 "\ 202} \ 204 \ 250"
(GDB) печати pHost-> h_length
$ 4 = 4
(GDB) печать тетср
$ 5 = {} 0x2fcf90
Так что я в основном распечатаны все это на линии 214. ('pHost-> h_addr_list [0]' является 'pHost-> h_addr' из-за «#define h_addr h_addr_list [ 0] ')
Я не смог поймать что-то неправильно. Вы поймали что-нибудь подозрительное? Возможно ли, что память была повреждена в другом месте? Я ценю вашу помощь!
[редактировать] 6. назад след
(GDB) BT
'# 0' 0x080e6433 в CLClient :: connectToServer (это = 0xf2afd898, Conn = 11) при liccomm/LClient .cpp: 214
'# 1' 0x080e6701 в CLClient :: connectToLMServer (это = 0xf2afd898) в liccomm/LClient.cpp: 121
... (Frames 2 ~ 7 опущено, не имеет значения)
'# 8' 0x080937f2 в handleConnectionStarter (п = 0xf3563f98) при LManager.cpp: 166
'# 9' 0xf7f5fb41 в ??()
'# 10' 0xf3563f98 in ??()
'# 11' 0xf2aff31c in ??()
'# 12' 0x00000000 in ??()
Я следил за вложенными вызовами. Они верны.
Первое, что нужно сделать, когда файл дампа ядра имеет значение «bt full», что даст вам полный стек вызовов в момент возникновения segfault. В большинстве случаев проблема кроется не в строке ошибки, а в некоторых случаях преждевременно, производя неправильные вызовы функций, которые в конечном итоге вызывают t он segfault. –
Спасибо Ян! Я использовал «bt» и «bt full». Вложенные вызовы действительны. Я отредактирую вопрос и опубликую вывод из bt. –
(GDB) BT # 0 0x080e6433 в CLClient :: connectToServer (это = 0xf2afd898, Conn = 11) при liccomm/LClient.cpp: 214 ... (Рамки 1 ~ 7 опущены, не имеет значения) # 8 0x080937f2 в handleConnectionStarter (par = 0xf3563f98) на LManager.cpp: 166 # 9 0xf7f5fb41 in ??() # 10 0xf3563f98 in ??() # 11 0xf2aff31c in ??() # 12 0x00000000 in ??() –