有了core-dump文件,BUG终于解决了!

【Linux Debug】如何生成core-dump文件?

See the source image

1、core-dump文件

首先,我们来明白core-dump文件是什么?保存了哪些信息?主要作用是什么?

core-dump文件,又称为核心转储,是操作系统在进程收到某些信号终止运行时,将此时进程的地址空间、进程状态以及其他信息写入到一个文件中,这个文件就是core-dump文件,其主要是为了方便开发人员调试,定位问题。

2、core-dump如何生成

core-dump文件是操作系统生成的,虽然是操作系统的事情,但是也得有个开关来把控吧!

那么如何生成core-dump文件呢?

2.1 打开core-dump开关

我们在命令行输入ulimit -a来查看相关信息:

dong@ubuntu:~$ ulimit -a
real-time non-blocking time  (microseconds, -R) unlimited
core file size              (blocks, -c) 0
data seg size               (kbytes, -d) unlimited
scheduling priority                 (-e) 0
file size                   (blocks, -f) unlimited
pending signals                     (-i) 18811
max locked memory           (kbytes, -l) 610792
max memory size             (kbytes, -m) unlimited
open files                          (-n) 1024
pipe size                (512 bytes, -p) 8
POSIX message queues         (bytes, -q) 819200
real-time priority                  (-r) 0
stack size                  (kbytes, -s) 8192
cpu time                   (seconds, -t) unlimited
max user processes                  (-u) 18811
virtual memory              (kbytes, -v) unlimited
file locks                          (-x) unlimited

注意core file size,该项表示了core-dump文件的大小限制,为0表示关闭!

我们输入ulimit -c unlimited,来将其大小设置为无限制,即可打开

2.2 路径设置

一般默认情况下,生成的core-dump文件在我们进程的当前目录下,要是我们想自定义保存路径该怎么办?

修改 /proc/sys/kernel/core_pattern文件!

例如:

echo "/data/coredump/corefile-%e-%p-%s-%t" > /proc/sys/kernel/core_pattern

/data/coredump/:为要设置的路径信息,如果不加路径信息,默认生成在进程目录下。

corefile-%e-%p-%s-%t:为设置的文件名称,这些特殊格式的意义如下:

#常用选项如下:
%p  #出Core进程的PID
%u  #出Core进程的UID
%s  #造成Core的signal号
%t  #出Core的时间,从1970-01-0100:00:00开始的秒数
%e  #出Core进程对应的可执行文件名

#完整如下:
Naming of core dump files
       By default, a core dump file is named core, but the /proc/sys/kernel/core_pattern file (since  Linux  2.6  and
       2.4.21)  can  be  set  to  define a template that is used to name core dump files.  The template can contain %
       specifiers which are substituted by the following values when a core file is created:

           %%  a single % character
           %c  core file size soft resource limit of crashing process (since Linux 2.6.24)
           %d  dump mode—same as value returned by prctl(2) PR_GET_DUMPABLE (since Linux 3.7)
           %e  executable filename (without path prefix)
           %E  pathname of executable, with slashes ('/') replaced by exclamation marks ('!') (since Linux 3.0).
           %g  (numeric) real GID of dumped process
           %h  hostname (same as nodename returned by uname(2))
           %i  TID of thread that triggered core dump, as seen in the PID  namespace  in  which  the  thread  resides
               (since Linux 3.18)
           %I  TID of thread that triggered core dump, as seen in the initial PID namespace (since Linux 3.18)
           %p  PID of dumped process, as seen in the PID namespace in which the process resides
           %P  PID of dumped process, as seen in the initial PID namespace (since Linux 3.12)
           %s  number of signal causing dump
           %t  time of dump, expressed as seconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC)
           %u  (numeric) real UID of dumped process

设置完成后,我们输入cat /proc/sys/kernel/core_pattern来查看文件是否设置成功!

到此,我们的core-dump就配置完成了,当发生崩溃或者异常终止的时候,就自动生成core-dump文件了。

2.3 特殊信息配置

这一部分,发现很少有人描述到,再此也记录一下!

core-dump信息还可以定制,在每个进程下,会有coredump_filter的一个文件(/proc/<pid>/coredump_filter),该文件会对core-dump生成的信息进行定制!

dong@ubuntu:~$ cat /proc/2395/coredump_filter 
00000033

一般coredump_filter的值为0x33,该值对应的信息如下:

  - (bit 0) anonymous private memory
  - (bit 1) anonymous shared memory
  - (bit 2) file-backed private memory
  - (bit 3) file-backed shared memory
  - (bit 4) ELF header pages in file-backed private memory areas (it is effective only if the bit 2 is cleared)
  - (bit 5) hugetlb private memory
  - (bit 6) hugetlb shared memory
  - (bit 7) DAX private memory
  - (bit 8) DAX shared memory

默认情况下,包含发生coredump时会将所有anonymous内存ELF头页面hugetlb private memory内容保存。

3、什么情况下产生core-dump文件?

发生core-dump一般都是在进程收到某个信号的时候,那么到底收到什么信号能够触发core-dump文件生成呢?

Linux上现在大概有60多个信号,可以使用 kill -l 命令全部列出来。

dong@ubuntu:~/WorkSpace/Donge_Programs/Donge_Demo/build$ kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

我们可以输入man 7 signal,来查看更加详细的SIGNAL信号信息!

       Signal      Standard   Action   Comment
       ────────────────────────────────────────────────────────────────────────
       SIGABRT      P1990      Core    Abort signal from abort(3)
       SIGALRM      P1990      Term    Timer signal from alarm(2)
       SIGBUS       P2001      Core    Bus error (bad memory access)
       SIGCHLD      P1990      Ign     Child stopped or terminated
       SIGCLD         -        Ign     A synonym for SIGCHLD
       SIGCONT      P1990      Cont    Continue if stopped
       SIGEMT         -        Term    Emulator trap
       SIGFPE       P1990      Core    Floating-point exception
       SIGHUP       P1990      Term    Hangup detected on controlling terminal
                                       or death of controlling process
       SIGILL       P1990      Core    Illegal Instruction
       SIGINFO        -                A synonym for SIGPWR
       SIGINT       P1990      Term    Interrupt from keyboard
       SIGIO          -        Term    I/O now possible (4.2BSD)
       SIGIOT         -        Core    IOT trap. A synonym for SIGABRT
       SIGKILL      P1990      Term    Kill signal
       SIGLOST        -        Term    File lock lost (unused)
       SIGPIPE      P1990      Term    Broken pipe: write to pipe with no
                                       readers; see pipe(7)
       SIGPOLL      P2001      Term    Pollable event (Sys V);
                                       synonym for SIGIO
       SIGPROF      P2001      Term    Profiling timer expired
       SIGPWR         -        Term    Power failure (System V)
       SIGQUIT      P1990      Core    Quit from keyboard
       SIGSEGV      P1990      Core    Invalid memory reference

       SIGSTKFLT      -        Term    Stack fault on coprocessor (unused)
       SIGSTOP      P1990      Stop    Stop process
       SIGTSTP      P1990      Stop    Stop typed at terminal
       SIGSYS       P2001      Core    Bad system call (SVr4);
                                       see also seccomp(2)
       SIGTERM      P1990      Term    Termination signal
       SIGTRAP      P2001      Core    Trace/breakpoint trap
       SIGTTIN      P1990      Stop    Terminal input for background process
       SIGTTOU      P1990      Stop    Terminal output for background process
       SIGUNUSED      -        Core    Synonymous with SIGSYS
       SIGURG       P2001      Ign     Urgent condition on socket (4.2BSD)
       SIGUSR1      P1990      Term    User-defined signal 1
       SIGUSR2      P1990      Term    User-defined signal 2
       SIGVTALRM    P2001      Term    Virtual alarm clock (4.2BSD)
       SIGXCPU      P2001      Core    CPU time limit exceeded (4.2BSD);
                                       see setrlimit(2)
       SIGXFSZ      P2001      Core    File size limit exceeded (4.2BSD);
                                       see setrlimit(2)
       SIGWINCH       -        Ign     Window resize signal (4.3BSD, Sun)

       The signals SIGKILL and SIGSTOP cannot be caught, blocked, or ignored.

我们可以看Action这一列,该列有几项,分别为TermCoreIgnStopCont

  • Term:terminal,终止程序!
  • Core:dump core,核心转储!
  • Ign:ignore,忽略信号
  • Stop:stop,停止进程
  • Cont:continue,继续执行进程

4、触发core-dump的信号处理流程

由上文可知,操作系统在接收到某个信号后,进而生成core-dump文件,那么该信号处理流程是怎么样的呢?

4.1 信号处理逻辑

img

我们把这个过程拆分成信号的接收、检测、处理三个步骤。

  • 信号接收接收信号的任务由内核代理,当内核接收到信号后,会将其放到对应进程的信号队列中,同时向进程发送一个中断,使其陷入内核态。注意,此时信号还只是在队列中,对进程来说暂时是不知道有信号到来的。
  • 信号检测:进程陷入内核态后,有两种场景会对信号进行检测:
    • 进程从内核态返回到用户态前进行信号检测
    • 进程在内核态中,从睡眠状态被唤醒的时候进行信号检测
  • 信号处理:信号处理函数是运行在用户态的,调用处理函数前,内核会将当前内核栈的内容备份拷贝到用户栈上,并且修改指令寄存器(eip)将其指向信号处理函数。接下来进程返回到用户态中,执行相应的信号处理函数。信号处理函数执行完成后,还需要返回内核态,检查是否还有其它信号未处理。如果所有信号都处理完成,就会将内核栈恢复(从用户栈的备份拷贝回来),同时恢复指令寄存器(eip)将其指向中断前的运行位置,最后回到用户态继续执行进程。

4.2 信号处理源码分析

img

进程从内核态返回到用户态的地方有很多,如 从系统调用返回从硬中断处理程序返回从进程调度程序返回 等。上图主要通过 从进程调度程序返回 作为示例,来展示内核是怎么生成 coredump 文件的。

4.2.1 do_signal()

当进程从 内核态 返回到 用户态 前,内核会查看进程的信号队列中是否有信号没有处理,如果有就调用 do_signal 内核函数处理信号。

static void fastcall do_signal(struct pt_regs *regs)
{
    siginfo_t info;
    int signr;
    struct k_sigaction ka;
    sigset_t *oldset;
 
    ...
    signr = get_signal_to_deliver(&info, &ka, regs, NULL);
    ...
}

上面代码去掉了很多与生成 coredump 文件无关的逻辑,最终我们可以看到,do_signal 函数主要调用 get_signal_to_deliver 内核函数来进行进一步的处理。

4.2.2 get_signal_to_deliver

get_signal_to_deliver 内核函数的主要工作是从进程的信号队列中获取一个信号,然后根据信号的类型来进行不同的操作。我们主要关注生成 coredump 文件相关的逻辑,如下代码:

int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
                          struct pt_regs *regs, void *cookie)
{
    sigset_t *mask = &current->blocked;
    int signr = 0;
 
    ...
    for (;;) {
        ...
        // 1. 从进程信号队列中获取一个信号
        signr = dequeue_signal(current, mask, info); 
 
        ...
        // 2. 判断是否会生成 coredump 文件的信号
        if (sig_kernel_coredump(signr)) {
            // 3. 调用 do_coredump() 函数生成 coredump 文件
            do_coredump((long)signr, signr, regs);
        }
        ...
    }
    ...
}

上面代码去掉了与生成 coredump 文件无关的逻辑,最后我们可以看到 get_signal_to_deliver 函数主要完成三个工作:

  • 调用 dequeue_signal 函数从进程的信号队列中获取一个信号。
  • 调用 sig_kernel_coredump 函数判断信号是否会生成 coredump 文件。
  • 如果信号会生成 coredump 文件,那么就调用 do_coredump 函数生成 coredump 文件。

4.2.3 do_coredump

如果要处理的信号会触发生成 coredump 文件,那么内核就会调用 do_coredump 函数来生成 coredump 文件。do_coredump 函数的实现如下:

int do_coredump(long signr, int exit_code, struct pt_regs *regs)
{
    char corename[CORENAME_MAX_SIZE + 1];
    struct mm_struct *mm = current->mm;
    struct linux_binfmt *binfmt;
    struct inode *inode;
    struct file *file;
    int retval = 0;
    int fsuid = current->fsuid;
    int flag = 0;
    int ispipe = 0;
 
    binfmt = current->binfmt; // 当前进程所使用的可执行文件格式(如ELF格式)
 
    ...
    // 1. 判断当前进程可生成的 coredump 文件大小是否受到资源限制
    if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
        goto fail_unlock;
 
    ...
    // 2. 生成 coredump 文件名
    ispipe = format_corename(corename, core_pattern, signr);
 
    ...
    // 3. 创建 coredump 文件
    file = filp_open(corename, O_CREAT|2|O_NOFOLLOW|O_LARGEFILE|flag, 0600);
 
    ...
    // 4. 把进程的内存信息写入到 coredump 文件中
    retval = binfmt->core_dump(signr, regs, file);
 
fail_unlock:
    ...
    return retval;
}

经过代码精简后,最终可以看到 do_coredump 函数完成四个工作:

  • 判断当前进程可生成的 coredump 文件大小是否受到资源限制。
  • 如果不受限制,那么调用 format_corename 函数生成 coredump 文件的文件名。
  • 接着调用 filp_open 函数创建 coredump 文件。
  • 最后根据当前进程所使用的可执行文件格式来选择相应的填充方法来填充 coredump 文件的内容,对于 ELF文件格式 使用的是 elf_core_dump 方法。

elf_core_dump 方法的主要工作是:把进程的内存信息和内容写入到 coredump 文件中,并且以 ELF文件格式 作为 coredump 文件的存储格式。有兴趣的可以自行阅读 elf_core_dump 方法的代码,这里就不作进一步的解说了。

补充:

信号处理线程:信号可以发给整个进程,也可以发给特定线程;发给整个进程的信号,随机选取一个线程进行执行;发给特定线程的信号,只能有特定的线程负责处理。一些信号如果是某些线程代码的直接执行而引发,那么只能由特定的线程负责执行,例如SIGILL, SIGSEG.

A signal may be directed to either the process as a whole or to a specific thread. A signal is thread-directed if it is generated as the direct result of the execution of a specific hardware instruction within the context of the thread (SIGBUS, SIGFPE, SIGILL, and SIGSEGV)

应用例子,比如进程触发了SIGSEG异常,我在异常处理函数中进行了while循环,最终仍然是卡死在异常线程的,此时可以看一下CPU占用率,哪个最高就是哪个线程触发的!

4.3 生产环境要不要打开core-dump限制

最后,我们来讨论一下在生产环境应不应该打开 coredump 功能。

最近遇过在生产环境打开 coredump 功能而导致的事故,故事如下:

最近我们的应用程序概率性极低出现SIGSEGV段错误,无论是DGB仿真还是排查代码,都不能直接定位到该问题所在。 为了能够抓到现场瞬间,我们就默认把coredump选项打开了,以便能够捕获到core-dump文件。 由于每次不单单只是SIGSEGV会引发core-dump文件,其他某些信号触发仍然会生成core-dump文件,这样随着一段时间过去,引发了一些OOM内存溢出的问题,或者磁盘变为只读,经过一些排查,发现core-dump文件异常的大,一个正常的文件都到300-500M,直接把磁盘撑爆了!!!

所以,经过上面的事故,我建议大家不要在生成环境打开 coredump 功能。

建议是拿出来一台机器特殊标记,打开 coredump 功能,然后模拟发生异常的情况来进行排查。生成 coredump 文件后,可以使用 GDB 来进行调试。

5、文章参考

[1]:https://zhuanlan.zhihu.com/p/240633280

[2]:https://blog.csdn.net/zhouhailiang1991/article/details/119172697

本文转载于网络 如有侵权请联系删除

相关文章

  • python中查看.db文件中表格的名字及表格中的字段操作

    1.问题描述:我桌面上有一个“账号密码.db”文件,我现在想知道里面有几张表格table、表格的名字、表头结构。2.使用SQL语句”””selectnamefromsqlite_masterwheretype=’table’orderbyname”””,查找表格的名字。实例代码如下:#coding:utf-8 importsqlite3 conn=sqlite3.connect("C:\Users\Administrator\Desktop\密码账号.db") cursor=conn.cursor() sql="""selectnamefromsqlite_masterwheretype='table'orderbyname""" cursor.execute(sql) result=cursor.fetchall() printresult printtype(result) conn.close()复制输出结果为:D:\Python3\python27\python.exeD:/Py

  • 基于maven+ssm的增删改查之前端校验数据合法性

    接上一节。直接在add.js中修改即可。如果index.jsp没有相应的id属性,直接加上匹配add.js中的即可。add.js//点击新增弹出模态框 $("#emp_add_modal_btn").click(function(){ //发送ajax请求,查出部门信息显示下拉列表 reset_form("#empAddModalform"); getDepts("#empAddModalselect"); $("#empAddModal").modal({ backdrop:"static" }); }); //清空表单样式和内容 functionreset_form(ele){ $(ele)[0].reset(); $(ele).find('*').removeClass("has-errorhas-success"); $(ele).find(".help-block").text(""); } //查

  • 17.【Kevin聊敏捷】敏捷项目管理之Sprint Review 迭代评审会

    SprintReview有的翻译为“冲刺评审会”,有的翻译为“迭代评审会”,其实都无所谓。它是在一个sprint快结束之际召开的。一、SprintReview概叙SprintReview的核心词是“Review”,但它不是不是让你把SprintReview开成“回顾会”,这是很多敏捷教练刚带团队的时候容易犯的错误。开SprintReview会的目的是演示这个Sprint中自己的工作成果,对于功能性的产品增量进行审视并调整。图一SprintProcess-SprintReview二、参与者出席会议的人有Scrum团队成员(产品负责人、DevelopmentTeam以及ScrumMaster),再加上客户、利益相关人、专家、领导层和任何有兴趣的人。图二参与的人员三、会议的形式1、可运行的产品才是这个阶段的核心在这个会议上,一定是拿出可以运行的产品,是让各干系人可以来体验产品,并且给到Scrum团队真实的反馈。评审会议中的一个关键元素是团队与产品负责人之间进行深入的对话来了解情况和得到建议等等。如果大家只是关注与产品而没有进行交谈,那就达不到真正的目的。更为糟糕的是Scrum团队拿出的是PP

  • 笑话:大厂都在用的任务调度框架我能不知道吗???

    前言我之前的工作中一直在用Elastic-Job来做任务调度。这也是大家为什么能在我的书籍《SpringCloud微服务入门实战与进阶》中看到Elastic-Job的章节。从2017的2.1.5版本之后Elastic-Job没再更新过。我们在做技术选型的时候,对框架的使用范围和社区的活跃度都会比较看重,当然首先是功能点能够满足业务需求。今天给大家新推荐一个任务调度框架,也许很多人听过甚至目前已经使用了很久。不过没关系,这也不影响你今天阅读本文章。这个框架就是XXL-JOB,一个轻量级分布式任务调度平台。最近在我的开源项目Kitty-Cloud中就采用了XXL-JOB,还有一个原因是我目前任职的公司也一直在使用XXL-JOB。XXL-JOB的前世今生XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。2015-11月,XXL-JOBRELEASE了第一个大版本V1.0,在后面的几年里一直在更新。目前最新的版本是今年更新的2.2.0。功能特性调度中心HA(中心式)执行器HA(分布式)执行器弹性扩容缩容

  • ICCV 2019 Oral | 三维"ZAO"脸,单张图片估计人脸几何,效果堪比真实皮肤

    CV君:本文为52CV群友上海科技大学陈安沛同学投稿,介绍了他们ICCV2019最新人脸3D重建的工作。效果非常赞,代码也已开源,欢迎大家参考~引言相比于最近几天刷遍朋友圈的“ZAO-缝脸造戏“和"DeepFake",今天我们提升一个维度,为给大家介绍如何从2D图片,"ZAO"出超逼真的3D人脸。这项工作已经被ICCV'19接收为Oralpaper。摘要如何通过单张图片恢复高质量的三维人脸是计算机视觉和图形学的重要研究领域,高质量的3D人脸通常指准确的几何、完整的纹理和真实的材质。在本文中,我们使用单张图片恢复带有皱纹细节的人脸几何,我们的算法可以分成proxyestimation(基础参数化模型估计)和detailssynthesis两个部分。对于proxyestimation,我们使用表情特征作为先验来应对3DMM参数估计时的ambiguity问题;对于detailssynthesis,我们采集了366个高精度三维人脸作为监督学习样本,同时结合基于重渲染误差的无监督学习来恢复人脸细节的displacementmap。相关工作前人在三

  • 网站漏洞修复工具对jsop协议漏洞分析

    六一儿童节快到了,最近出了太多太多的漏洞,像前几天被爆出的cve-2019-0708漏洞,利用的是windows服务器远程桌面rdp协议进行的攻击,今天来给大家送一个礼物是关于网站方面的,jsonp漏洞可以导致csrf网站攻击。很多人会把jsonp跟json当成是一个东西,但真实情况不是这样的,先来介绍一下什么是jsonp,简单来讲就是一个可以解决网站跨域请求访问的一个语言,可以帮助网站跨域的去请求参数,使数据之间同步,很好的解决不同网站之间的通信问题。关于网站漏洞的JSONP劫持漏洞,我们来详细的分析看下。一般网站在设计功能过程加入jsonp实例代码,比如下面这一段,图1:使用的是php语言开发的,很简单的一个第三方jsonp接口,返回用户名和密码,当get请求的时候就会返回我们需要的值,如果我们对callback值进行修改的时候,返回的值也会有所改变,那么这里就可以被我们利用,修改成恶意的代码,来欺骗用户点击,从而向服务器端里的json接口进行请求,当用户输入账号密码等信息的时候就已经不知不觉的提交到了攻击者的网站里,用户密码被泄露。如下图:JSONP漏洞应该算是属于csrf攻击,

  • Material的布局原则

    原则MaterialDesign指南通过源自印刷领域的设计元素–例如排版、网格、空白、缩放、颜色,和图像–来建立层次结构和传达所要表达的含义,并专注于带给用户沉浸式的体验。MaterialDesign采用来自印刷设计领域的工具,如基准网格和结构模版,通过重复视觉元素,结构网格以及跨平台和屏幕尺寸的间距,促进不同环境下设计的一致性。这些布局可通过缩放来适应任何屏幕大小,这简化了创建可扩展应用的过程。纸片工作原理在MaterialDesign中,纸片的物理特性被转移到了屏幕中。应用的背景类似于一张平坦、不透明质地的纸片,应用的行为也模仿纸片,可以改变大小、拖动及把多个纸片粘合在一起。在本规范中,构成应用的表面被成为材料或材料片。应用之外的元素,例如系统状态栏,和应用内容是分开的,不会被视为材料。更多关于材料的细节,详见材料属性。接缝两片材料的公共边缘被成为接缝。当通过接缝连接时,它们会一起移动。两片材料的接缝阶层两个Z轴位置不同的材料片重叠时,会形成阶层。这两个材料会相互独立移动。两片重叠的材料构成的阶层浮动操作按钮浮动操作按钮浮动操作按钮是和工具栏分离的圆形纸片。它表示单个被提升的操作。

  • Android查缺补漏(IPC篇)-- 进程间通讯之AIDL详解

    本文作者:CodingBlock文章链接:http://www.cnblogs.com/codingblock/p/8436529.html在上一篇博文中介绍了一种轻量级的跨进程通讯方案-Messenger,Messenger实现起来非常简单,其底层原理也是AIDL,更像是一个简易版的AIDL,但简单的东西往往也有其局限性,Messenger的主要作用是传递消息,它无法实现RPC功能也就是无法让我们在客户端本地就能调用远程的方法,而且Messenger是以串行的方式处理,无法同时处理多个请求,只能一个一个的处理。而AIDL就可以很好弥补Messenger的不足,虽然实现起来相对复杂一些,但它功能强大,无疑是跨进程通讯的首选方案。接下来我们先看看AIDL是什么,都可以传递哪些数据,并且本文会用一个小例子来直观的体会AIDL的实现过程。读完本文你将深入掌握以下几个知识点:AIDL是什么?AIDL传递的类型。怎么创建AIDL。AIDL文件中的定向tag:in、out、inout的区别。如何在AIDL中添加权限校验。一、AIDL是什么?AIDL全称AndroidInterfaceDefinit

  • 一种简单的Failover机制

    在应用结构上有这样一个业务场景,机房里部署了多个物理数据库的Proxy无状态节点,业务端通过Proxy节点间接和存储DB交互。Proxy支持了分库分表的特性,管理下层多个物理DB,向上层提供单表抽象。为了支持高可用性,Proxy为多节点部署,业务端可以随机挑选Proxy收发消息。这里我们讨论业务端SDK的Failover实现方案。SDK需要管理指向多个Proxy连接,每个请求都需要随机挑选某个Proxy连接进行收发消息。当Proxy都正常时,随机算法已经可以满足负载均衡了。但是Proxy是可能会突然宕机的,挂了一个Proxy节点后,SDK需要快速摘除宕机的Proxy连接,将所有的请求都转移到其它节点之上。当这个Proxy节点恢复后,又可以重新将这个节点放回Proxy列表中。那这种快速的动态调整,SDK又该如何以最简单的方法进行实现呢?一般的思路如下使用计数机制,当请求出现错误时,比如在一定的时间窗口里出现了N次错误,那就可以标记该Proxy已损坏,从Proxy正常列表中摘除掉该Proxy,同时在恢复列表中加入该Proxy使用Retry机制,每隔一段时间对恢复列表中的Proxy进行重试,

  • android 单元测试(1)无依赖测试

        单元测试不适用于测试复杂的界面交互事件。后者应改用界面测试框架。   1.官方文档   https://developer.android.google.cn/training/testing/unit-testing?hl=zh-cn   https://github.com/android/testing-samples/tree/master/unit/BasicUnitAndroidTest   https://junit.org/junit4/index.html   https://junit.org/junit4/javadoc/latest/overview-summary.html   https://github.com/junit-team/junit4/wiki/Getting-started  junit使用教程   https://developer.android.google.cn/training/testing/set-up-project   https://developer.android.goo

  • 文件在线预览doc,docx转换pdf(一)

    文件在线预览doc,docx转换pdf(一) 1. 前言 文档转换是一个是一块硬骨头,但是也是必不可少的,我们正好做的知识库产品中,也面临着同样的问题,文档转换,精准的全文搜索,知识的转换率,是知识库产品的基本要素,初识阅读时同时绞尽脑汁,自己开发?,集成第三方?都是中小企业面临的一大难题……. 自己在网上搜索着找到poi开源出来的很多例子,最开始是用poi把所有文档转换为html, 1) 在github上面找到一个https://github.com/litter-fish/transform完整的demo,你想要的转换基本都提供,初学者可以参照实现转换出来的基本样子,达到通用级别,需要自己花很多功夫。此开源代码是基于poi和itext(pdf)的转换方式。 2) https://gitee.com/kekingcn/file-online-preview这是开源中国提供的一个源码,基于jodconverter,原理是调用windows,另存为的组件,实现转换。 3) 收费产品例如【永中office】【office365】【idocv】、【https://downloads.aspo

  • [HNOI2016] 序列

    题目链接: 序列 题目分析: 看到询问跳来跳去,各个询问之间的计算又有重叠部分,考虑能不能莫队一下 麻烦的是如何\(O(1)\)求\(l,r\)指针挪动一格的时候更新答案 以考虑挪动右指针为例 \([l,r]\rightarrow[l,r+1]\) 新产生的区间是所有以\(r+1\)为右端点,左端点在\([l,r+1]\)内的所有区间 然后我们发现最小值是一段一段出现的 举个例子 216345 假设我们固定右端点,把左端点从1挪到5,那么对应每个区间的最小值就是 113345 可以发现不仅成段而且还递增,这个是易证的 考虑能不能预处理出每一段的起始结束位置,计算贡献就可以用\((最小值覆盖区间长度)*当前最小值\)来计算了 有一个常用的\(trick\)是处理出每个数前面第一个比它小的数\(pre_i\),这个可以用单调栈做到\(O(n)\) 然后可以得到一个式子,其中\(f_i\)表示右端点钦定为\(i\),左端点位于\(1\)到\(i\)的所有区间的最小值之和 \(f_i=f_{pre_i}+(i-pre_i)*a[i]\) 即当左端点在\(pre_i\)前面的时候,我们直接把\(

  • Python3.7 安装

    Linux 依赖包安装 yum-yinstallwgetmakegcc yum-yinstallzlib-develbzip2-developenssl-develncurses-develsqlite-develreadline-develtk-develgdbm-develdb4-devellibpcap-develxz-devellibffi-devel 下载安装包 wgethttps://www.python.org/ftp/python/3.7.0/Python-3.7.0.tgz 创建存放目录 mkdir/usr/local/python3 解压 tar-zxvfPython-3.7.0.tgz cdPython-3.7.0 指定编译目录 ./configure--prefix=/usr/local/python3 编译安装 make&&makeinstall 建立软链接 ln-s/usr/local/python3/bin/python3.7/usr/bin/python3 ln-s/usr/local/python3/bin/pip3.7/usr/bin

  • 构建调试Linux内核网络代码的环境MenuOS系统

     一,安装并编译最新版Linux内核 mkdir/Linux cd~/Linux/ wgethttps://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.0.1.tar.xz xz-dlinux-5.0.1.tar.xz tar-xvflinux-5.0.1.tar cdlinux-5.0.1复制 因为之前我在嵌入式Linux中做过类似的实验,我用到的编译工具为gcc交叉编译工具链:用以下命令安装: sudoapt-getinstallgcc-arm-linux-gnueabi复制 接下来我们设置编译文件: sudomakemenuconfig复制 注:menuconfig图形化.config设置界面需要安装前置库libncurses-dev,直接sudo安装即可,打开menuconfig如下: 之后用键盘↑↓键依次选择Kernelhacking,Compile-timechecksandcompileroptions,[*]Compilethekernelwith debug info &nbs

  • 阿里云(Ubuntu20.04)搭建wordpress全流程——附图超详细版

    【本文基于Windows10的Powershell,使用ssh连接服务器】 1、在阿里云控制台上的操作 (1)获得实例公网IP      (2)更改实例密码,以后用于远程连接       2、配置环境 (0)首先我们打开powershell(win+R召出如下窗口)       (1)远程连接服务器 sshroot@123.123.123.123(公网IP)复制   输入刚刚在控制台设置的密码之后按回车。     ※如果之前重置了服务器,可能出现这样的状况。 PSC:\Users\AL76>sshroot@123.123.123.123(公网IP) @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @WARNING:REMOTEHOSTIDENTIFICATIONHASCHANGED!@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ IT

  • 高级软件工程第六次作业:LLS团队作业-3

    1.需求&原型改进   1.1 给目标用户展示原型,并进一步沟通理解需求      ①我们的目标用户是评分者用户      ②思考用户痛点,描述使用场景。      场景一:对于唱歌,跳舞,表演,演讲,朗诵等文艺、文化类的比赛,需综合观众和评委的评分评选出冠军和给出相应的排名的比赛,观众用户投票给自己喜欢的选手,从主观程度投票,并不具有较强的客观性,从而直接影响比赛的排名,导致比赛结果存在争议的后果。 这个情景存在的痛点:观众用户主观性较强行为直接影响比赛结果、比赛结果存在争议。      场景二:对于一个唱歌比赛,从系统用户内筛选出此比赛相似度最高的权威性的评委用户,和对比赛具有较强专业性的观众用户。由他们根据选手比赛时的表现,给出专业性较强的评分结果,最后比赛结果争议几乎没有。      从这个场景中我们可以知道大家都接受了比赛的最后结果。   1.2 修改完善上周完成的《需求规格说明书》         ①《需求规格说明书》coding地址:https://git.coding.net/Ssl_dhlg18/SIMsystem.git      ②场景

  • P3327 [SDOI2015]约数个数和

    \[d(ij)=\sum_{x|i}\sum_{y|j}[\gcd(x,y)=1]\\ \]\[\sum_{i=1}^{n}\sum_{j=1}^{m}\sum_{x|i}\sum_{y|j}[\gcd(x,y)=1]\\ \sum_{x=1}^{n}\sum_{y=1}^{m}[\gcd(x,y)=1]\sum_{i=1}^{\fracnx}\sum_{j=1}^{\fracmy}1\\ \sum_{x=1}^{n}\sum_{y=1}^{m}(\fracnx)(\fracmy)\sum_{p|x,p|y}\mu(p)\\ \sum_{p=1}^{n}\mu(p)\sum_{x=1}^{\fracnp}\sum_{y=1}^{\fracmp}(\fracn{xp})(\fracm{yp})\\ \]

  • 软件工程——总结

    这个作业属于哪个课程|https://edu.cnblogs.com/campus/xnsy/Autumn2019SoftwareEngineeringFoundation ---|:--?--- 这个作业要求在哪里|https://edu.cnblogs.com/campus/xnsy/Autumn2019SoftwareEngineeringFoundation/homework/10119 团队名称|狙击旷课特勤队 这个作业的目标|1.学习团队项目合作2.学习编程工具的运用3.学习相关的编程流程与知识 GitHub地址|https://github.com/Dedicate-labors/Ray-classroom/tree/master 队员列表 职务 学号 姓名 博客链接 队长 061425 zxl 队员 061423 zn https://www.cnblogs.com/wxllovezn/p/11997348.html 队员 061424 zrq https://www.cnblogs.com/zrqzzj/p/12000237.html 队员

  • Mysql配置文件 My.ini(版本8.0)

       今天修改了My.ini的默认编码之后,发现无法启动Mysql服务器了。这是因为在修改保存之后,My.ini格式发生了变化,变成了UTF8格式了,但是服务器读取配置文件的时候,不能识别这个编码。 解决方法:    1:用记事本打开My.ini,然后在另存为的时候,将格式保存为ANSI保存之后就可以解决问题。   你的时间用在哪里决定你成为一个什么样的人。

  • bash命令的使用

    bash的工作特性之命令执行状态返回值和命令展开所涉及的内容及其示例演出 !脚本执行与调试 1、绝对路径执行,要求文件有执行权限 2、以sh命令执行,不要求文件有执行权限 3、.加空格或source命令执行,脚本将在当前shell中执行 4、检查脚本语法 bash-vtest.sh 5、跟踪脚本执行 bash-xtest.sh !环境脚本执行规则 用户登录:/etc/profile、/.bash_profile、/.bash_login、~/.profile 用户注销:~/.bash_logout 执行新shell:/etc/bash.bashrc、~/.bashrc 执行script(使用#!/bin/bash):如指定BASH_ENV的值,则执行其指定的启动文件 执行script(使用#!/bin/sh):不调用任何环境脚本 !基本语法 1、脚本程序以#!/bin/bash开始。以告之系统脚本以何种shell执行。 2、以#开头的行被视为注解,执行时自动忽略。 3、每行不得多于255个字节,可在行末加上反斜杠的方式拆分单行内容到多行中。 例如: test1=abcdefg hij

  • (课内)信安数基quiz3

    题干-分析-exp:      

相关推荐

推荐阅读