1. 程式人生 > >linux crash在動態庫中,通過map查詢crash位置

linux crash在動態庫中,通過map查詢crash位置

linux程序crash時,通常我們可以通過gdb+core或addr2line解析出程序crash在哪一個函式中,有時crash在動態連結庫中,解析出的core可能只有一個地址,而不能知道是在哪一個函式,這時可以嘗試通過/proc/程序ID/maps的方法找到crash的位置。

一個動態庫的實現:

標頭檔案sample_fun.h

#ifndef _SAMPLE_FUN_H_
#define _SAMPLE_FUN_H_

void testFun4();

#endif

原始檔sample_fun.cpp
#include <stdio.h>
#include "sample_fun.h"

void testFun4()
{
   int* p = NULL;
   printf("%d", *p); //will crash
}


使用g++將這個原始檔編譯出動態庫

g++ -fPIC -shared sample_fun.cpp -o libsample_fun.so

呼叫動態庫的實現sample_main.cpp

#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

#include "sample_fun.h"

using namespace std;

#define BUFFLEN 256

void testFun1();
void testFun2();
void testFun3();

int main(int argc, char** argv)
{
   int pid = getpid();
   char cmdBuf[BUFFLEN] = {0x00};
   sprintf(cmdBuf, "cat /proc/%d/maps > /home/nap/%d.maps", pid, pid); //save current process maps
   system(cmdBuf);

   testFun1();
}

void testFun1()
{
   testFun2();
}

void testFun2()
{
   testFun3();
}

void testFun3()
{
   testFun4(); //call this function will crash
}


將這個檔案編譯可執行程式並連線動態庫

g++ sample_main.cpp -L. libsample_fun.so -o sample_main

執行著個程式發生了crash,並且生成了core檔案,

./sample_main 

Segmentation fault (core dumped)

通過gdb+core看到了crash的地址

GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 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 "i686-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /home/nap/sample_main...(no debugging symbols found)...done.
[New LWP 4170]


warning: Can't read pathname for load map: Input/output error.
Core was generated by `./sample_main'.
Program terminated with signal 11, Segmentation fault.
#0  0xb773a478 in ???
(gdb) bt
#0  0xb773a478 in ???
#1  0x08048770 in ???
#2  0x08048763 in ???
(gdb) 

通過檢視程序的map可以看出crash的位置在libsample_fun.so的程式碼段,

08048000-08049000 r-xp 00000000 08:05 1059318    /home/nap/sample_main
08049000-0804a000 r--p 00000000 08:05 1059318    /home/nap/sample_main
0804a000-0804b000 rw-p 00001000 08:05 1059318    /home/nap/sample_main
b7449000-b744b000 rw-p 00000000 00:00 0 
b744b000-b7467000 r-xp 00000000 08:05 1311741    /lib/i386-linux-gnu/libgcc_s.so.1
b7467000-b7468000 r--p 0001b000 08:05 1311741    /lib/i386-linux-gnu/libgcc_s.so.1
b7468000-b7469000 rw-p 0001c000 08:05 1311741    /lib/i386-linux-gnu/libgcc_s.so.1
b7469000-b7493000 r-xp 00000000 08:05 1315013    /lib/i386-linux-gnu/libm-2.15.so
b7493000-b7494000 r--p 00029000 08:05 1315013    /lib/i386-linux-gnu/libm-2.15.so
b7494000-b7495000 rw-p 0002a000 08:05 1315013    /lib/i386-linux-gnu/libm-2.15.so
b7495000-b7638000 r-xp 00000000 08:05 1310845    /lib/i386-linux-gnu/libc-2.15.so
b7638000-b763a000 r--p 001a3000 08:05 1310845    /lib/i386-linux-gnu/libc-2.15.so
b763a000-b763b000 rw-p 001a5000 08:05 1310845    /lib/i386-linux-gnu/libc-2.15.so
b763b000-b763f000 rw-p 00000000 00:00 0 
b763f000-b7717000 r-xp 00000000 08:05 1575071    /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b7717000-b7718000 ---p 000d8000 08:05 1575071    /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b7718000-b771c000 r--p 000d8000 08:05 1575071    /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b771c000-b771d000 rw-p 000dc000 08:05 1575071    /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b771d000-b7724000 rw-p 00000000 00:00 0 
b773a000-b773b000 r-xp 00000000 08:05 1059319    /home/nap/libsample_fun.so
b773b000-b773c000 r--p 00000000 08:05 1059319    /home/nap/libsample_fun.so
b773c000-b773d000 rw-p 00001000 08:05 1059319    /home/nap/libsample_fun.so
b773d000-b773f000 rw-p 00000000 00:00 0 
b773f000-b7740000 r-xp 00000000 00:00 0          [vdso]
b7740000-b7760000 r-xp 00000000 08:05 1311879    /lib/i386-linux-gnu/ld-2.15.so
b7760000-b7761000 r--p 0001f000 08:05 1311879    /lib/i386-linux-gnu/ld-2.15.so
b7761000-b7762000 rw-p 00020000 08:05 1311879    /lib/i386-linux-gnu/ld-2.15.so
bf97d000-bf99e000 rw-p 00000000 00:00 0          [stack]

接下來我們要求出crash的函式在libsample_fun.so中的地址,計算方式如下

發生crash的地址 - 動態庫的起始地址 + 偏移地址

在我們的例子中為0xb773a478 - 0xb773a000 + 0x00000000 = 0x478

通過 nm -n libsample_fun.so將這個動態庫中的符號表按地址順序輸出

[email protected]:~$ nm -n libsample_fun.so 
         w _Jv_RegisterClasses
         w [email protected]@GLIBC_2.1.3
         w __gmon_start__
         U [email protected]@GLIBC_2.0
00000330 T _init
000003a0 t __do_global_dtors_aux
00000420 t frame_dummy
00000457 t __i686.get_pc_thunk.bx
0000045c T _Z8testFun4v
000004a0 t __do_global_ctors_aux
000004d8 T _fini
00000574 r __FRAME_END__
00001f14 d __CTOR_LIST__
00001f18 d __CTOR_END__
00001f1c d __DTOR_LIST__
00001f20 d __DTOR_END__
00001f24 d __JCR_END__
00001f24 d __JCR_LIST__
00001f28 a _DYNAMIC
00001ff4 a _GLOBAL_OFFSET_TABLE_
0000200c d __dso_handle
00002010 A __bss_start
00002010 A _edata
00002010 b completed.6159
00002014 b dtor_idx.6161
00002018 A _end

找到最接近0x478且比0x478下的地址,這個地址的函式就是發生crash的函式

使用c++filt將這個函式名打印出來

[email protected]:~$ c++filt _Z8testFun4v
testFun4()

這樣我們就找到了crash的函式。

相關推薦

linux crash動態通過map查詢crash位置

linux程序crash時,通常我們可以通過gdb+core或addr2line解析出程序crash在哪一個函式中,有時crash在動態連結庫中,解析出的core可能只有一個地址,而不能知道是在哪一個函式,這時可以嘗試通過/proc/程序ID/maps的方法找到crash的

linux程序裏面知道一個函數地址改函數是屬於某個動態怎麽樣得到這個動態的全【轉】

main 動態庫 360doc 復制 address 函數 地址 ati content 轉自:http://www.360doc.com/content/17/1012/11/48326749_694292472.shtml 另外dl_iterate_phdr可以查到當

如何理解Linux下的動態概念和靜態概念通俗易懂的解釋如下:

動態庫和靜態庫都是一組函式集合,打包在一起供應用程式呼叫,區別是: 靜態庫名稱一般為xxx.a,在編譯時和應用程式連結在一起,這樣的應用程式佔用空間較大。 動態庫名稱一般為xxx.so,對於動態庫即可以在編譯時連結,也可以使用dlopen()/dlsy

如何檢視linux動態包含哪些函式

1、方法1 nm *.so 2、方法2 readelf -a *.so PS:readelf Options are: -a --all Equivalent to: -h -l -S -s -r -d -V -A -I

linux下檢視動態的符號

功能 列出.o .a .so中的符號資訊,包括諸如符號的值,符號型別及符號名稱等。所謂符號,通常指定義出的函式,全域性變數等等。 使用 nm [option(s)] [file(s)] 有用的options: -A 在每個符號資訊的前面列印所在物件檔名稱;-C

通過readelf檢視動態的內容

readelf是unix下檢視庫中連結的內容工具。elf:Executable and Linkable Format mac下的安裝以及使用方法: 1、下載binutils-2.24.tar.gz 2、解壓 3、安裝(使用disable-werror是為了防止mac上ma

linux區域網通過主機名進行通訊

 在一個區域網中,每臺機器都有一個主機名,用於主機與主機之間的便於區分,就可以為每臺機器設定主機名,以便於以容易記憶的方法來相互訪問。比如我們在區域網中可以為根據每臺機器的功用來為其命名。主機名相關的配置檔案:/etc/hosts;    hosts 配置檔案是用來把主機

EF Core通過實體類向SQL Server數據插入數據後實體對象是如何得到數據的默認值的

ask asd target 主鍵 行數 create count declare bold 我們使用EF Core的實體類向SQL Server數據庫表中插入數據後,如果數據庫表中有自增列或默認值列,那麽EF Core的實體對象也會返回插入到數據庫表中的默認值。

生產環境通過域名映射ip切換工具SwitchHosts

data sts track ack switch driver eve tail blog 項目中,經常需要配置host。將某個域名指向某個ip。手動配置C:\Windows\System32\drivers\etc\hosts,非常不方便。這裏分享一個可以高效切換hos

c++動態使用命名空間的問題

family 不能 eight 函數 names bsp ++ data- color 這是C++才會有的語言特性. 假如你使用一個程序庫,他裏面有桓霰淞拷衋bc,可是你自己也不小心定義了一個叫abc的變量,這樣就會引起重定義錯誤.所以為了避免這樣

linux IP動態變動之後 需要做的雜項操作

需要 alt gin col font img linux linux ip 不變 linux的動態ip經常變來變去,目前還沒找到固定它不變化的方法。所以每次變動之後都需要做以下的操作,極其麻煩。(必須找到讓linux IP 固定的方法) 1.先找到變化之後的動態ip地

查詢cad所有程序leg引用的點的id需要預先處理點表和程序表

nbsp pro rom 倒序 sele 引用 air 處理 _id select f1.pro_id,f1.pro_type, f1.code_fix_point, f1.code_type_fix_point, f1.code_fir,f2.code_icao,nvl(

關系數據索引的作用主要有哪些一般什麽情況下需要建索引?並簡述索引都有哪幾種類型有何區別

出了 分組 臨時 key 全文索引 兩個 關系數據庫 情況下 普通 提高查詢速度,有利於排序和分組. (排序和分組如用不上索引,則會產生臨時表和filesort的過程) 根據業務邏輯,分析列查詢的頻度和順序, 建立索引和復合索引. 主鍵索引(primary key), --

Oracle數據使用存儲過程將BLOB字段批量導成JPG格式

pda 路徑 fclose lac ima har 版本 很慢 註意 環境說明:   照片:存放在生產庫中的用戶 picmgr 中,數據庫版本為ORACLE10g;   目的:將照片導到本地路徑 D:\image ,存儲格式為 jpg 。 第一步:在本地安裝or

C#調用非托管動態的函數方法

left tom -c too normal evel idt col class C#如何調用一個非托管動態庫中的函數呢,比如用VC6寫的動態庫,總之C#調用動態庫的過程是比Java調用DLL動態庫方便快捷多了,下面舉例說明這個過程。 1、創建一個非托管動態庫 代碼

linux數據使用MD5加密

insert lba log 字符 sele div sql 技術 sqlite MD5加密算法源碼下載:https://pan.baidu.com/s/1nwyN0xV 下載完成了之後解壓,得到兩個文件 環境搭建: 1、把md5.h文件拷貝到/usr/include

談談Linux動態查找路徑的問題

是你 一個 pat 找不到 nbsp style 探討 environ mic 原文地址: http://blog.chinaunix.net/uid-23069658-id-4028681.html 學習到了一個階段之後,就需要不斷的總結、沈澱、清零,然後才能繼續“上路”

微信公眾號跳轉到小程序通過api

log ini post 推送 打開 key 配置 media 二級菜單 參數是否必須說明button是一級菜單數組,個數應為1~3個sub_button否二級菜單數組,個數應為1~5個type是菜單的響應動作類型,view表示網頁類型,click表示點擊類型,mini

在laravel使用DB查詢數據返回的對象可以用下面的辦法變為數組

UNC lar class div nod 使用 get() map account $nodes = Db::table(‘account‘)->orderBy(‘sort‘, ‘asc‘)->orderBy(‘id‘ ,‘asc‘)->get()-&g

【Python求助】在eclipse和pycharm通過adb install安裝中文名字APK時老是報錯如何解決

style com all auto RoCE mod python lin sage 1 # -*- coding: utf-8 -*- 2 import os 3 import sys 4 import subprocess 5 import time 6 from