wip post
This commit is contained in:
parent
c8a2913172
commit
5a1c98d8a4
8 changed files with 170 additions and 0 deletions
2
content/posts/debugging-rr-children/.gitignore
vendored
Normal file
2
content/posts/debugging-rr-children/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
/crasher
|
||||||
|
/caller
|
||||||
5
content/posts/debugging-rr-children/Makefile
Normal file
5
content/posts/debugging-rr-children/Makefile
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
CFLAGS = -g
|
||||||
|
all: caller crasher
|
||||||
|
.PHONY: all
|
||||||
|
caller: caller.o
|
||||||
|
crasher: crasher.o
|
||||||
21
content/posts/debugging-rr-children/caller.c
Normal file
21
content/posts/debugging-rr-children/caller.c
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
int pid = fork();
|
||||||
|
if (pid == -1) {
|
||||||
|
perror("fork");
|
||||||
|
return 1;
|
||||||
|
} else if (pid == 0) {
|
||||||
|
execl("./crasher", "./crasher", NULL);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
// parent
|
||||||
|
int status;
|
||||||
|
printf("[caller] spawned pid %d\n", pid);
|
||||||
|
int ret = waitpid(pid, &status, 0);
|
||||||
|
printf("[caller] waitpid: %d, exited? %d status %d, signaled? %d signal %d\n", ret, WIFEXITED(status), WEXITSTATUS(status), WIFSIGNALED(status), WTERMSIG(status));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
7
content/posts/debugging-rr-children/crasher.c
Normal file
7
content/posts/debugging-rr-children/crasher.c
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
printf("[crasher] about to crash\n");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
80
content/posts/debugging-rr-children/index.md
Normal file
80
content/posts/debugging-rr-children/index.md
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
+++
|
||||||
|
date = "2022-02-24"
|
||||||
|
draft = false
|
||||||
|
path = "/blog/debugging-rr-children"
|
||||||
|
tags = []
|
||||||
|
title = "Debugging: using rr to deal with unruly children (processes)"
|
||||||
|
+++
|
||||||
|
|
||||||
|
I have done multiple rounds of debugging blobs of processes that start together
|
||||||
|
and then something bad happens in one of the children several forks down.
|
||||||
|
Although gdb claims to support child processes with `set follow-fork-mode`
|
||||||
|
([docs][gdb-follow-fork-mode]), in practice, this is extremely painful since
|
||||||
|
you may have to set it to multiple different things in one reproduction.
|
||||||
|
|
||||||
|
To deal with these, I've done such hacks as writing wrapper scripts for the
|
||||||
|
executable at fault that run it in a gdbserver. However, by far the worst one
|
||||||
|
I've done is printing out the PID of the misbehaving process then waiting, to
|
||||||
|
give me time to attach the debugger ([this is even suggested in the gdb
|
||||||
|
documentation][gdb-sleep]).
|
||||||
|
|
||||||
|
[gdb-follow-fork-mode]: https://docs.jade.fyi/gnu/gdb/gdb.html#index-set-follow_002dfork_002dmode
|
||||||
|
[gdb-sleep]: https://docs.jade.fyi/gnu/gdb/gdb.html#Forks
|
||||||
|
|
||||||
|
## Using rr to do it the easy way
|
||||||
|
|
||||||
|
For this demo, I am using two programs I wrote:
|
||||||
|
|
||||||
|
- `crasher` just prints out that it's about to crash, then aborts.
|
||||||
|
- `caller` forks and executes `crasher`, then prints its return value once it
|
||||||
|
exits.
|
||||||
|
|
||||||
|
These are written in C but their source is not super interesting. Nevertheless,
|
||||||
|
you can find their source code [at the bottom of the post](#source).
|
||||||
|
|
||||||
|
Here they are in action:
|
||||||
|
|
||||||
|
```
|
||||||
|
» ./caller
|
||||||
|
[caller] spawned pid 158938
|
||||||
|
[crasher] about to crash
|
||||||
|
[caller] waitpid: 158938, exited? 0 status 0, signaled? 1 signal 6
|
||||||
|
```
|
||||||
|
|
||||||
|
Signal 6, if you consult the table in `man 'signal(7)'`, is `SIGABRT` as
|
||||||
|
expected.
|
||||||
|
|
||||||
|
We want to figure out why the crasher is crashing. It's possible to do with
|
||||||
|
gdb, but that's unnecessarily hard because of gdb, even moreso if it forks
|
||||||
|
multiple times.
|
||||||
|
|
||||||
|
Let's use `rr` to do this more easily. First, record a run:
|
||||||
|
|
||||||
|
```
|
||||||
|
» rr record ./caller
|
||||||
|
rr: Saving execution to trace directory `/home/lf/.local/share/rr/caller-0'.
|
||||||
|
[caller] spawned pid 159146
|
||||||
|
[crasher] about to crash
|
||||||
|
[caller] waitpid: 159146, exited? 0 status 0, signaled? 1 signal 6
|
||||||
|
```
|
||||||
|
|
||||||
|
Then find the process ID of the crashing process:
|
||||||
|
|
||||||
|
```
|
||||||
|
» rr ps
|
||||||
|
PID PPID EXIT CMD
|
||||||
|
159145 -- 0 ./caller
|
||||||
|
159146 159145 -6 ./crasher
|
||||||
|
```
|
||||||
|
|
||||||
|
Next, use either `--onfork=<PID>` or `--onprocess=<PID>` to get a debugger on
|
||||||
|
the problem process:
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Demo source {#source}
|
||||||
|
|
||||||
|
{{ codefile(path="caller.c", code_lang="c", colocated=true, hide=true) }}
|
||||||
|
{{ codefile(path="crasher.c", code_lang="c", colocated=true, hide=true) }}
|
||||||
|
{{ codefile(path="Makefile", code_lang="make", colocated=true, hide=true) }}
|
||||||
36
templates/macros/code.html
Normal file
36
templates/macros/code.html
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
{%- import "macros/colocated_asset.html" as colocated_asset -%}
|
||||||
|
|
||||||
|
<!-- Load a file and dump it in a code block. -->
|
||||||
|
{%- macro file(path, code_lang=false, colocated=false,
|
||||||
|
hide=false, show_path_with_prefix=false) -%}
|
||||||
|
|
||||||
|
{%- set newline = "
|
||||||
|
" -%}
|
||||||
|
{%- set mypath = path -%}
|
||||||
|
|
||||||
|
{%- if show_path_with_prefix == false -%}
|
||||||
|
{%- set header = "" -%}
|
||||||
|
{%- else -%}
|
||||||
|
{%- set header = show_path_with_prefix ~ " " ~ path ~ newline -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- if colocated == true -%}
|
||||||
|
{%- set path = colocated_asset::colocated_asset(path=path) | trim -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- if code_lang == true -%}
|
||||||
|
{%- set code_lang = '' -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- set data = load_data(path=path, format="plain") -%}
|
||||||
|
{%- set source = "```" ~ code_lang ~ newline ~ header ~ data ~ newline ~ "```" | safe -%}
|
||||||
|
|
||||||
|
|
||||||
|
{%- if hide == true -%}
|
||||||
|
<details>
|
||||||
|
<summary>
|
||||||
|
<code>{{ mypath }}</code>
|
||||||
|
</summary>
|
||||||
|
{%- endif -%}
|
||||||
|
{{ source | markdown(inline=true) | safe }}
|
||||||
|
{%- if hide == true -%}
|
||||||
|
</details>
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endmacro file -%}
|
||||||
10
templates/macros/colocated_asset.html
Normal file
10
templates/macros/colocated_asset.html
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
<!--
|
||||||
|
Returns the file path of the colocated asset.
|
||||||
|
When Zola uses `resize_image` it looks relative to the `content` folder.
|
||||||
|
This means you have to reference the full page asset colocation path.
|
||||||
|
-->
|
||||||
|
{%- macro colocated_asset(path) -%}
|
||||||
|
{%- set page_url_components = page.relative_path | default(value=section.relative_path) | split(pat='/') -%}
|
||||||
|
{%- set page_base = page_url_components | slice(end=page_url_components | length - 1) | join(sep='/') -%}
|
||||||
|
{{ page_base ~ '/' ~ path }}
|
||||||
|
{%- endmacro colocated_asset -%}
|
||||||
9
templates/shortcodes/codefile.html
Normal file
9
templates/shortcodes/codefile.html
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
{%- import "macros/code.html" as code -%}
|
||||||
|
|
||||||
|
{{ code::file(
|
||||||
|
path=path,
|
||||||
|
code_lang=code_lang | default(value=''),
|
||||||
|
colocated=colocated | default(value=false),
|
||||||
|
hide=hide | default(value=false),
|
||||||
|
show_path_with_prefix=show_path_with_prefix | default(value=false)
|
||||||
|
) }}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue