admin 管理员组

文章数量: 1184232


2024年1月18日发(作者:webapp的优缺点)

1

2

3

4

5

6

7

extern

"C"Elf32_Addr __linker_init(void* raw_args) {

Elf32_Addr start_address = __linker_init_post_relocation(args, linker_addr);

set_soinfo_pool_protection(PROT_READ);

// Return the address that the calling assembly stub should jump to.

returnstart_address;} 1

2

3

4

5

staticElf32_Addr __linker_init_post_relocation(KernelArgumentBlock& args, Elf32_Addr linker_base) {

...

debuggerd_init();

...}bioniclinkerDebugger.c 1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

voiddebugger_init(){

struct sigaction act;

memset(&act,

0, sizeof(act));

_sigaction = debugger_signal_handler;

_flags = SA_RESTART | SA_SIGINFO;

sigemptyset(&_mask);

sigaction(SIGILL, &act, NULL);

sigaction(SIGABRT, &act, NULL);

sigaction(SIGBUS, &act, NULL);

sigaction(SIGFPE, &act, NULL);

sigaction(SIGSEGV, &act, NULL);

sigaction(SIGSTKFLT, &act, NULL);

sigaction(SIGPIPE, &act, NULL);}

18

19* local socket but we need to tell it our tid. It

20* is paranoid and will verify that we are giving a tid

21* that's actually in our process

22*/

23int

ret;

24

debugger_msg_t msg; 25

= DEBUGGER_ACTION_CRASH; 26

= tid; 27

RETRY_ON_EINTR(ret, write(s, &msg, sizeof(msg))); 28

if(ret == sizeof(msg)) { 29

/* if the write failed, there is no point to read on 30

* the file descriptor. */ 31

RETRY_ON_EINTR(ret, read(s, &tid,

321

)); 33

intsavedErrno = errno; 34

notify_gdb_of_libraries(); 35

errno = savedErrno; 36

} 37

38

if 39(ret <

0) { 40

/* read or write failed -- broken connection? */ 41

format_buffer(msgbuf, sizeof(msgbuf), 42

"Failed while talking to debuggerd: %s" 43, strerror(errno));

44__libc_android_log_write(ANDROID_LOG_FATAL,

"libc", msgbuf); 45

} 46

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

close(s);

}

else{

/* socket failed; maybe process ran out of fds */

format_buffer(msgbuf, sizeof(msgbuf),

"Unable to open connection to debuggerd: %s", strerror(errno));

__libc_android_log_write(ANDROID_LOG_FATAL,

"libc", msgbuf);

}

/* remove our net so we fault for real when we return */

signal(n, SIG_DFL);

/*

* These signals are not re-thrown when we resume. This means that

* crashing due to (say) SIGPIPE doesn't work the way you'd expect it

* to. We work around this by throwing them manually. We don't want

* to do this for *all* signals because it'll screw up the address for

* faults like SIGSEGV.

*/

switch(n) {

caseSIGABRT:

caseSIGFPE:

caseSIGPIPE:

caseSIGSTKFLT:

(void

10

switch 11(signum) {

12case

SIGILL: signame =

"SIGILL" 13;

break; 14

case 15SIGABRT: signame =

"SIGABRT";

16break

; 17

caseSIGBUS: signame =

18"SIGBUS"

;

break 19;

20case

SIGFPE: signame =

"SIGFPE" 21;

break; 22

case 23SIGSEGV: signame =

"SIGSEGV";

24break

; 25

caseSIGSTKFLT: signame =

26"SIGSTKFLT"

;

break 27;

28case

SIGPIPE: signame =

"SIGPIPE" 29;

break; 30

default: signame =

"";

break;

}

if(prctl(PR_GET_NAME, (unsigned

long)threadname,

0,

0,

0) !=

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

* debuggerd crashes can't be reported to debuggerd. Reset all of the

* crash handlers.

*/

signal(SIGILL, SIG_DFL);

signal(SIGABRT, SIG_DFL);

signal(SIGBUS, SIG_DFL);

signal(SIGFPE, SIG_DFL);

signal(SIGSEGV, SIG_DFL);

signal(SIGPIPE, SIG_IGN);

signal(SIGSTKFLT, SIG_DFL);

logsocket = socket_local_client("logd",

ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_DGRAM);

if(logsocket <

0) {

logsocket = -1;

}

else{

fcntl(logsocket, F_SETFD, FD_CLOEXEC);

}

_handler = SIG_DFL;

sigemptyset(&_mask);

sigaddset(&_mask,SIGCHLD);

_flags = SA_NOCLDWAIT;

sigaction(SIGCHLD, &act,

0);

37

38

s = socket_local_server(DEBUGGER_SOCKET_NAME,

ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM); 39

40if

(s <

0 41)

return1 42;

43fcntl(s, F_SETFD, FD_CLOEXEC);

44

45LOG(

"debuggerd: "__DATE__

46" "

__TIME__

"n" 47);

48

49//check corefile limit.

50(

void)check_corefile_limit(); 51

52

for 53(;;) {

54struct sockaddr addr;

55socklen_t alen;

56int

fd; 57

alen = sizeof(addr); 58

XLOG("waiting for connectionn" 59);

fd = accept(s, &addr, &alen);

if(fd <

0) {

XLOG("accept failed: %sn", strerror(errno));

continue;

17

18

19

20

*

* The PTRACE_ATTACH sends a SIGSTOP to the target process, but it

* won't necessarily have stopped by the time ptrace() returns. (We

* currently assume it does.) We write to the file descriptor to

* ensure that it can run as soon as we call PTRACE_CONT below. 21

* See details in bionic/libc/linker/debugger.c, in function 22

* debugger_signal_handler(). 23

*/ 24

if 25(ptrace(PTRACE_ATTACH, ,

0,

260

)) { 27

LOG("ptrace attach failed: %sn" 28, strerror(errno));

29}

else{ 30

bool detach_failed =

31false

; 32

bool attach_gdb = should_attach_gdb(&request); 33

if(TEMP_FAILURE_RETRY(write(fd,

34"0"

,

1 35)) !=

1) { 36

LOG( 37"failed responding to client: %sn"

, strerror(errno)); 38

}

else 39{

40char

* tombstone_path = NULL; 41

42

if( == DEBUGGER_ACTION_CRASH) { 43

close(fd); 44

fd = -

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

fd = -1;

}

inttotal_sleep_time_usec =

0;

for(;;) {

intsignal = wait_for_signal(, &total_sleep_time_usec);

if(signal <

0) {

break;

}

switch(signal) {

caseSIGSTOP:

if( == DEBUGGER_ACTION_DUMP_TOMBSTONE) {

XLOG("stopped -- dumping to tombstonen");

tombstone_path = engrave_tombstone(, ,

signal,

true,

true, &detach_failed,

&total_sleep_time_usec);

}

elseif( == DEBUGGER_ACTION_DUMP_BACKTRACE) {

XLOG("stopped -- dumping to fdn");

dump_backtrace(fd, , , &detach_failed,

73&total_sleep_time_usec);

74}

else{ 75

XLOG( 76"stopped -- continuingn"

); 77

status = ptrace(PTRACE_CONT, ,

0 78,

0); 79

if 80(status) {

81LOG(

"ptrace continue failed: %sn", strerror(errno)); 82

} 83

continue 84;

/* loop again */ 85

} 86

break; 87

88

case 89SIGILL:

90case

SIGABRT: 91

caseSIGBUS: 92

case 93SIGFPE:

94case

SIGSEGV: 95

caseSIGSTKFLT: { 96

XLOG( 97"stopped -- fatal signaln"

); 98

/* 99

* Send a SIGSTOP to the process to make all of

* the non-signaled threads stop moving. Without

100

101

102

103

104

105

106

107

* this we get a lot of "ptrace detach failed:

* No such process".

*/

kill(, SIGSTOP);

/* don't dump sibling threads when attaching to GDB because it

* makes the process less reliable, */

tombstone_path = engrave_tombstone(, ,

108

signal, !attach_gdb,

false 109, &detach_failed,

110&total_sleep_time_usec);

111break

; 112

} 113

114

caseSIGPIPE: 115

LOG( 116"socket-client process stopped due to SIGPIPE! n"

); 117

break; 118

119

default 120:

121XLOG(

"stopped -- unexpected signaln"); 122

LOG( 123"process stopped due to unexpected signal %dn"

, signal); 124

break; 125

} 126

break 127;

128}

129

130

if( == DEBUGGER_ACTION_DUMP_TOMBSTONE) {

131

if(tombstone_path) { 132

write(fd, tombstone_path, strlen(tombstone_path)); 133

} 134

close(fd); 135

fd = - 1361

; 137

} 138

free(tombstone_path); 139

} 140

141

XLOG("detachingn" 142);

143if

(attach_gdb) { 144

/* stop the process so we can debug */ 145

kill(, SIGSTOP); 146

147

/* detach so we can attach gdbserver */ 148

if(ptrace(PTRACE_DETACH, ,

1490

,

0 150)) {

LOG("ptrace detach from %d failed: %sn", , strerror(errno));

detach_failed =

true;

}

/*

* if is set, its value indicates if we should wait

* for user action for the crashing process.

* in this case, we log a message and turn the debug LED on

* waiting for a gdb connection (for instance)

*/

wait_for_user_action();

}

else{

/* just detach */

if(ptrace(PTRACE_DETACH, ,

0,

0)) {

LOG("ptrace detach from %d failed: %sn", , strerror(errno));

detach_failed =

true;

}

}

/* resume stopped process (so it can crash in peace). */

kill(, SIGCONT);

/* If we didn't successfully detach, we're still the parent, and the

* actual parent won't receive a death notification via wait(2). At this point

* there's not much we can do about that. */

if(detach_failed) {

LOG("debuggerd committing suicide to free the zombie!n");

kill(getpid(), SIGKILL);

}

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

pollfds[0].fd = fd;

pollfds[0].events = POLLIN;

pollfds[0].revents =

0;

status = TEMP_FAILURE_RETRY(poll(pollfds,

1,

3000));

if(status !=

1) {

LOG("timed out reading tidn");

return-1;

}

debugger_msg_t msg;

status = TEMP_FAILURE_RETRY(read(fd, &msg, sizeof(msg)));

if(status <

0) {

LOG("read failure? %sn", strerror(errno));

return-1;

}

if(status != sizeof(msg)) {

LOG("invalid crash request of size %dn", status);

return

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

return-1;

}

out_request->action = ;

out_request->tid = ;

out_request->pid = ;

out_request->uid = ;

out_request->gid = ;

if( == DEBUGGER_ACTION_CRASH) {

/* Ensure that the tid reported by the crashing process is valid. */

charbuf[64];

struct stat s;

snprintf(buf, sizeof buf,

"/proc/%d/task/%d", out_request->pid, out_request->tid);

if(stat(buf, &s)) {

LOG("tid %d does not exist in pid %d. ignoring debug requestn",

out_request->tid, out_request->pid);

return-1;

}

}

elseif( ==

0

|| ( == AID_SYSTEM && == DEBUGGER_ACTION_DUMP_BACKTRACE)) {

/* Only root or system can ask us to attach to any process and dump it explicitly.

* However, system is only allowed to collect backtraces but cannot dump tombstones. */

status = get_process_info(out_request->tid, &out_request->pid,

&out_request->uid, &out_request->gid);

if(status <

0) {

LOG("tid %d does not exist. ignoring explicit dump requestn",

out_request->tid);

return-1;

}

}

else{

/* No one else is not allowed to dump arbitrary processes. */

return-1;

}

return0;} 从socket中读取client端进程的pid uid gid 1

getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &len); 轮询socket句柄

1

2

3

4

5

struct pollfd pollfds[1];pollfds[0].fd = fd;pollfds[0].events = POLLIN;pollfds[0].revents =

0;status = TEMP_FAILURE_RETRY(poll(pollfds,

1,

3000)); 从socket上读取debugger_msg_t结构体 1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

debugger_msg_t msg;status = TEMP_FAILURE_RETRY(read(fd, &msg, sizeof(msg)));if(status <

0) {

LOG("read failure? %sn", strerror(errno));

return-1;}if(status != sizeof(msg)) {

LOG("invalid crash request of size %dn", status);

return-1;}out_request->action = ;out_request->tid = ;out_request->pid = ;out_request->uid = ;out_request->gid = ; 如果debugger_msg_t中设置的action为DEBUGGER_ACTION_CRASH,说明是crash的C/C++进程发来的请求,则判断传进来的tid是否有效。

28

} 29

break; 30

case 31SIGILL:

32case

SIGABRT: 33

caseSIGBUS: 34

case 35SIGFPE:

36case

SIGSEGV: 37

caseSIGSTKFLT: { 38

XLOG( 39"stopped -- fatal signaln"

); 40

kill(, SIGSTOP); 41

tombstone_path = engrave_tombstone(, ,

signal, !attach_gdb,

false, &detach_failed,

&total_sleep_time_usec);

break;

}

caseSIGPIPE:

LOG("socket-client process stopped due to SIGPIPE! n");

break;

default:

XLOG("stopped -- unexpected signaln");

LOG("process stopped due to unexpected signal %dn", signal);

14char

task_path[64 15];

16snprintf(task_path, sizeof(task_path),

"/proc/%d/task", pid); 17

DIR* d = opendir(task_path); 18

if 19(d) {

20struct dirent debuf;

21struct dirent *de;

22while

(!readdir_r(d, &debuf, &de) && de) { 23

if(!strcmp(de->d_name,

24"."

) || !strcmp(de->d_name,

".." 25)) {

26continue

; 27

} 28

29

char* end; 30

pid_t new_tid = strtoul(de->d_name, &end,

3110

); 32

if(*end || new_tid == tid) { 33

continue 34;

35}

dump_thread(&log, new_tid, context,

false, detach_failed, total_sleep_time_usec);

}

closedir(d);

}

return1;

}

}

if(!have_tid) {

usage();

return1;

}

returndo_explicit_dump(tid, dump_backtrace);}通过do_explicit_dump函数dump出指定进程的栈信息等

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

staticintdo_explicit_dump(pid_t tid, bool dump_backtrace) {

fprintf(stdout,

"Sending request to dump task %d.n", tid);

if(dump_backtrace) {

fflush(stdout);

if(dump_backtrace_to_file(tid, fileno(stdout)) <

0) {

fputs("Error dumping backtrace.n", stderr);

return1;

}

}

else{

chartombstone_path[PATH_MAX];

if(dump_tombstone(tid, tombstone_path, sizeof(tombstone_path)) <

0) {

fputs("Error dumping tombstone.n", stderr);

本文标签: 进程 请求 指定 进来

更多相关文章

svchost.exe大解析:掌握Windows操作系统的运行关键

1月前

svchost.exe 是 Windows 系统的 核心服务宿主进程,并非独立程序,而是负责承载多个系统服务(如自动更新、网络连接等;以 DLL 形式存在)的“容器”,正常情况下会在任务管理器中显示多个实例,属

从SVCHOST到SWF:探析其背后的合作与支持关系

1月前

你是否经常在你电脑看到很多 svchost.exe进程呢?有的人电脑有6个svchost.exe进程、有的人电脑更多的svchost.exe进程。例如我的电脑就有5个svchost.exe程序。一般来说Wind

走近svchost.exe与hkcmd.exe:揭秘这两个进程的幕后操作

1月前

进程文件: Svchost.exe Svchost.exe文件存在于“%system root%system32”(例如C:Windowssystem32)目录下,它是Windows NT核心的重

Linux高手进阶课:用netstat和ps找出并释放被占用的端口

1月前

运行软件或程序时,有时会出现以下问题、导致运行失败: Web server failed to start. Port 8080 was already in use. 表示8080端口被占用,程序启动失败。

一招解决8092端口占用难题:确保Flash中心流畅运行

1月前

端口占用处理 项目启动报端口正在使用 09:25:12.866 [restartedMain]ERROR org.springframework.boot.diagnostics.LoggingFailureAnalys

摆脱技术难题:快速解决RBCShellExternal带来的烦扰

1月前

迅雷影音被自动安装后,已经卸载,但是每天还是会定时弹出“影音资讯”弹窗,如下图,让人烦得很,下面操作可以让你摆脱烦恼:C盘直接搜索KKTIP会发现在路径C:UsersPublicVideo LegendRBC

电脑故障排查指南:识别并解决DLLHOST.EXE相关的Adobe Flash Player问题

1月前

dllhost.exe 是 Windows 系统的核心进程之一,主要作用是管理和运行系统中的 COM+ 组件,属于正常且必要的系统进程。 1. 正常 dllhost.exe 的核心信息 进程定位:它

Java程序问题解决高手必备:dump文件生成与解析攻略

1月前

为啥需要内存文件 服务器CPU,内存占用空间飙升,或者GC频繁,首先需要排除的就是内存泄露,即内存中没有的对象的空间没有被及时回收导致的。而检测内存泄露就需要看哪种类在内存占了较多份额,从而定位到代码,然后修改。

这SVCHOST.exe吃CPU吃得厉害,怎么处理才对?能强行终结吗?

1月前

svchost.exe是什么意思? svchost.exe是Windows操作系统中一个非常重要且合法的核心进程,它的名字是Service Host(服务宿主)的缩写。简单来说,它是动态链接库(DLL)中运行的服务的通

巧用ClipBoardSvcGroup,让SWF内容在Adobe Flash Player上焕发生机的实践指南

1月前

转载 本文转载自,防止原站挂了。作者:ZwelL 1. 多个服务共享一个Svchost.exe进程利与弊 windows 系统服务分为独立进程和共享进程两种,在windows NT时只有服务器

深入探究svchost.exe:了解Windows后台运行的奥秘

1月前

svchost是微软Windows操作系统中的系统文件程序,这个程序对系统的正常运行是非常重要,而且是不能被结束的,许多服务通过注入到该程序中启动,所以会有多个该文件的进程。推荐:《编程视频》svchost.e

深入探究:SVCHOST.EXE在电脑中的角色和重要性

1月前

网上有很多关于是什么进程,svchost.exe是什么病毒,svchost.exe占用cpu100%或占用大量内存,svchost.exe有十几个,svchost.exe偷偷连网很象木马的问题,本文提供关于svchost.exe

深入浅出:解析Android中的App与桌面进程的不同之处

1月前

安卓 有三类工作和三种进程 动作 RemoteView 纯静态 UI渲染 读取本地静态数据、一些同步的计算逻辑、views.setTextViewText()等普通 KotlinJava

在Linux系统中让Chromium浏览器像服务一样稳定运行的方法分享

1月前

前言:很多时候,有些程序需要开机自启动,有很多种方式可以实现,我这里写了俩种方式,一是桌面进程,二是守护进程。 一、桌面进程示例 1.文件需是xxx.desktop命名,路径需在~.config下 ~.confi

一键搞定!教你如何在Linux上自动启动Chromium桌面应用程序

1月前

前言:很多时候,有些程序需要开机自启动,有很多种方式可以实现,我这里写了俩种方式,一是桌面进程,二是守护进程。 一、桌面进程示例 1.文件需是xxx.desktop命名,路径需在~.config下 ~.confi

微信登陆不求人!用wxshareutils轻松搞定

1月前

微信分享Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.wx_fxlogo);图标Wx

一文精通Redis读写之道:避开穿透风险,提升性能的旁路技巧

1月前

一、Redis三种常用的缓存读写策略 Redis有三种读写策略分别是:旁路缓存模式策略、读写穿透策略、异步缓存写入策略。 这三种缓存读写策略各有优势,不存在最佳,需要我们根据实际的业务场景选择最合适的。 二、旁路缓存模式(Cache

从经典到智能:Web演进之路与未来趋势探析

1月前

大家好,今天想和大家深度拆解我们每天高频接触,却鲜少深究的「Web 世界」。从最初仅能承载文字与图片的静态页面,到如今集沉浸式交互、智能服务、全端适配于一体的复杂应用生态,Web 的发展历程,本质上是一部「技术迭代适配用户需求」的浓缩

Windows-mscorsvw.exe

15天前

mscorsvw.exe是 Microsoft .NET Framework(微软.NET框架)的核心系统进程,全称为 Microsoft .NET Runtime Optimizat

【学习笔记】Android进程调度及优化_processstate foreground visible

10天前

1.ADJ算法 1.1 ADJ级别 ADJ级别定义在 com.android.server.am.ProcessList.java中,oom_adj划分为16级,分别如下所示(Android 1

发表评论

全部评论 0
暂无评论