diff options
Diffstat (limited to '_notes')
| -rw-r--r-- | _notes/bash.html | 184 | ||||
| -rw-r--r-- | _notes/gdb.md | 135 | ||||
| -rw-r--r-- | _notes/latex.md | 38 | ||||
| -rw-r--r-- | _notes/makefile.md | 129 | ||||
| -rw-r--r-- | _notes/markdown.md | 44 |
5 files changed, 0 insertions, 530 deletions
diff --git a/_notes/bash.html b/_notes/bash.html deleted file mode 100644 index c401522..0000000 --- a/_notes/bash.html +++ /dev/null @@ -1,184 +0,0 @@ ---- -title: bash -subtitle: best practices -layout: nosidebar -links: - - {rel: stylesheet, href: 'assets/css/guides.css'} -features: - - title: Script header - topics: - - do: - - | - #!/usr/bin/env bash - - set -o errexit -o nounset -o pipefail - shopt -s inherit_errexit lastpipe - dont: - - | - #!/bin/sh -e - - title: Arrays - topics: - - title: Declaration - do: - - | - local -a xs=() - declare -a xs=() - local -A xs=() - declare -A xs=() - dont: - - | - local -a xs - declare -a xs - local -A xs - declare -A xs - - # Doesn't work with nounset: - echo "${#xs[@]}" - - title: Expansion - do: - - | - func ${arr[@]+"${arr[@]}"} - dont: - - | - # Doesn't work with nounset: - func "${arr[@]}" - - | - # Expands to 0 arguments instead of 1: - declare -a arr=('') - func "${arr[@]+"${arr[@]}"}" - - title: unset - do: - - | - unset -v 'arr[x]' - unset -v 'arr[$i]' - dont: - - | - # May break due to globbing: - unset -v arr[x] - # In addition, possible quoting problem: - unset -v arr[$i] - # Doesn't work for some reason: - unset -v 'arr["x"]' - unset -v 'arr["]"]' - # Also rejected: - unset -v 'arr["$i"]' - - # An insightful discussion on the topic: - # https://lists.gnu.org/archive/html/help-bash/2016-09/msg00020.html - - title: errexit - topics: - - title: Command substitution - do: - - | - shopt -s inherit_errexit - - foo() { echo foo ; } - bar() { false ; echo bar >&2 ; } - - output="$( bar )" - foo "$output" - - # If inherit_errexit is unavailable, you can do - #output="$( set -e; bar )" - dont: - - | - foo() { echo foo ; } - bar() { false ; echo bar >&2 ; } - - # This will print both "foo" and "bar": - foo "$( bar )" - # This will also print "foo": - foo "$( false )" - - | - foo() { echo foo ; } - bar() { false ; echo bar >&2 ; } - - # This will still print both "foo" and "bar". - output="$( bar )" - foo "$output" - - # This won't print anything. - output="$( false )" - foo "$output" - - title: Process substitution - do: - - | - shopt -s lastpipe - - result=() - cmd | while IFS= read -r line; do - result+=("$( process_line "$line" )") - done - dont: - - | - # Without lastpipe, the loop is executed is a subshell, - # and the array will be empty: - result=() - cmd | while IFS= read -r line; do - result+=("$( process_line "$line" )") - done - - | - # errexit doesn't work for <( cmd ) no matter what: - while IFS= read -r line; do - process_line "$line" - done < <( cmd ) - # This will be printed even if cmd fails: - echo 'should never see this' - - | - # This breaks if $output contains the \0 byte: - output="$( cmd )" - - while IFS= read -r line; do - process_line "$line" - done <<< "$output" - - title: Functions - do: - - | - foo() { false ; echo foo >&2 ; } - - foo - echo ok - dont: - - | - foo() { false ; echo foo >&2 ; } - - # This will print "foo" no matter what. - if foo; then - echo ok - fi - - # Same below. - foo && echo ok - foo || echo fail - - # It currently appears to be completely impossible to - # execute a function inside a conditional with errexit - # enabled. Therefore, you should try to avoid this - # whenever possible. ---- -{% for feature in page.features %} - <h2>{{ feature.title }}</h2> - {% for topic in feature.topics %} - {% if topic.title %} - <h3>{{ topic.title }}</h3> - {% endif %} - <div class="row"> - <div class="col-md-6"> - {% for guide in topic.do %} - <div class="pre_container pre_do"> - {% highlight bash %}{{ guide }}{% endhighlight %} - <div class="pre_mark"><span class="glyphicon glyphicon-ok"></span></div> - </div> - {% endfor %} - </div> - <div class="col-md-6"> - {% for guide in topic.dont %} - <div class="pre_container pre_dont"> - {% highlight bash %}{{ guide }}{% endhighlight %} - <div class="pre_mark"><span class="glyphicon glyphicon-remove"></span></div> - </div> - {% endfor %} - </div> - </div> - {% endfor %} -{% endfor %} diff --git a/_notes/gdb.md b/_notes/gdb.md deleted file mode 100644 index 47db5c9..0000000 --- a/_notes/gdb.md +++ /dev/null @@ -1,135 +0,0 @@ ---- -title: gdb -subtitle: cheat sheet -links: - - {rel: stylesheet, href: 'assets/css/gdb.css'} ---- -Core dumps ----------- - -* Where are my core dumps? - - cat /proc/sys/kernel/core_pattern - -* Put core dumps in a directory: - - mkdir /coredumps - chmod 0777 /coredumps - echo '/coredumps/core.%e.%p' | tee /proc/sys/kernel/core_pattern - -* Still no dumps :-( - - ulimit -c unlimited - -* If dumps are piped to systemd-coredump, you can examine them using -`coredumpctl`. - - <div markdown="1" class="table-responsive"> - | List dumps | `coredumpctl` - | Debug the last dump | `coredumpctl gdb` - | Extract the last dump | `coredumpctl dump -o core` - {: .table .table-bordered } - </div> - -.gdbinit --------- - - # Without these, gdb is hardly usable: - set pagination off - set confirm off - set print pretty on - - # Save history: - set history save on - set history filename ~/.gdb-history - set history size 10000 - -Basics ------- - -<div markdown="1" class="table-responsive"> - -| Run | `r` -| Continue | `c` -| Breakpoint at function | `b FUNC` -| Breakpoint at address | `b *0xdeadbeef` -| List breakpoints | `i b` -| Disable breakpoint | `dis N` -| Enable breakpoint | `en N` -| Delete breakpoint | `d N` -| Call stack | `bt` -| Call stack: all threads | `thread apply all bt` -| Go to frame | `f N` -| Switch to thread | `t N` -| Disassemble | `disas FUNC` -| Step over line | `n` -| Step over instruction | `si` -| Step out of frame | `fin` -{: .table .table-bordered } - -</div> - -Hint: put this in your ~/.gdbinit and use `bta` as a shortcut: - - define bta - thread apply all backtrace - end - -Data inspection ---------------- - -<div markdown="1" class="table-responsive"> - -| Disassemble 5 instructions | `x/5i 0xdeadbeef` -| Print a 64-bit address | `x/1xg 0xdeadbeef` -| Print a 32-bit address | `x/1xw 0xdeadbeef` -| Print anything | `p sa->__sigaction_handler.sa_handler` -| Describe a type | `ptype struct sigaction` -| Describe a type with offsets | `ptype /o struct sigaction` -| Disassemble all code sections | `objdump -d /proc/self/exe` -| Disassemble a single section | `objdump -d -j .init /proc/self/exe` -| Display the section contents | `objdump -s -j .data /proc/self/exe` -{: .table .table-bordered } - -</div> - -Hint: put this in your ~/.gdbinit: - - define xxd - dump binary memory /tmp/dump.bin $arg0 ((char *)$arg0)+$arg1 - shell xxd -groupsize 1 /tmp/dump.bin - shell rm -f /tmp/dump.bin - end - -You can then use `xxd ADDR LEN` to display, in my opinion, the best formatting -for memory dumps: - - (gdb) xxd main 24 - 00000000: f3 0f 1e fa 41 57 41 89 ff bf 05 00 00 00 41 56 ....AWA.......AV - 00000010: 49 89 f6 41 55 41 54 55 I..AUATU - -Debuginfod ----------- - -If your distribution provides a Debuginfod server, use it! -For example, see [Arch], [Debian], [Fedora]. -In ~/.gdbinit, add - - set debuginfod enabled on - -[Arch]: https://wiki.archlinux.org/title/Debuginfod -[Debian]: https://wiki.debian.org/Debuginfod -[Fedora]: https://fedoraproject.org/wiki/Debuginfod - - -Intel syntax ------------- - -This is just me being a baby duck. -In ~/.gdbinit: - - set disassembly-flavor intel - -With `objdump`: - - objdump -Mintel -d /proc/self/exe diff --git a/_notes/latex.md b/_notes/latex.md deleted file mode 100644 index 35e4a7d..0000000 --- a/_notes/latex.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: LaTeX -subtitle: document template ---- -A more-or-less complete, but still very basic LaTeX document follows. - -```tex -\documentclass[11pt]{article} - -% Basic setup -\usepackage{cmap} -\usepackage[utf8]{inputenc} -\usepackage[T1]{fontenc} % Use T2A for non-ASCII scripts -\usepackage[english]{babel} - -% Completely arbitrary settings follow: - -% Sans serif font by default -\renewcommand\familydefault{\sfdefault} - -% Document margins -\usepackage[margin=2.5cm]{geometry} - -% Paragraph indents -\usepackage{parskip} -\setlength\parindent{0cm} -\setlength\parskip{0cm} - -% URLs -\usepackage[colorlinks=true,urlcolor=blue]{hyperref} - -\begin{document} - -Hello, \LaTeX! -Repository link: \href{https://github.com/egor-tensin/blog}{https://github.com/egor-tensin/blog}. - -\end{document} -``` diff --git a/_notes/makefile.md b/_notes/makefile.md deleted file mode 100644 index 62e0570..0000000 --- a/_notes/makefile.md +++ /dev/null @@ -1,129 +0,0 @@ ---- -title: make -subtitle: best practices -layout: nosidebar -links: - - {rel: stylesheet, href: 'assets/css/guides.css'} -features: - - note: This should go on top of every Makefile. - sections: - - do: - - | - MAKEFLAGS += --no-builtin-rules --no-builtin-variables --warn-undefined-variables - unexport MAKEFLAGS - .DEFAULT_GOAL := all - .DELETE_ON_ERROR: - .SUFFIXES: - SHELL := bash - .SHELLFLAGS := -eu -o pipefail -c - - escape = $(subst ','\'',$(1)) - - define noexpand - ifeq ($$(origin $(1)),environment) - $(1) := $$(value $(1)) - endif - ifeq ($$(origin $(1)),environment override) - $(1) := $$(value $(1)) - endif - ifeq ($$(origin $(1)),command line) - override $(1) := $$(value $(1)) - endif - endef - - note: Quote command arguments and use the `escape` function on variables and shell output. - sections: - - do: - - | - var := Includes ' quote - test: - printf '%s\n' '$(call escape,$(var))' - dont: - - | - var := Includes space - test: - printf '%s\n' $(var) - - | - var := Includes ' quote - test: - printf '%s\n' '$(var)' - - do: - - | - cwd := $(shell pwd) - test: - printf 'In directory %s\n' '$(call escape,$(cwd))' - dont: - - | - cwd := $(shell pwd) - test: - printf 'In directory %s\n' $(cwd) - - | - cwd := $(shell pwd) - test: - printf 'In directory %s\n' '$(cwd)' - - note: Use the `noexpand` function on environment variables or variables that can be overridden on the command line. - sections: - - do: - - | - has_default ?= Default value - $(eval $(call noexpand,has_default)) - - test: - echo '$(call escape,$(has_default))' - dont: - - | - has_default ?= Default value - - test: - echo '$(call escape,$(has_default))' - - | - has_default ?= Default value - export has_default - - test: - echo "$$has_default" - - do: - - | - $(eval $(call noexpand,ENV_VAR)) - - test: - echo '$(call escape,$(ENV_VAR))' - dont: - - | - test: - echo '$(call escape,$(ENV_VAR))' ---- -I've made a [detailed blog post] about how all of this works. -{: .alert .alert-info } - -[detailed blog post]: {% post_url 2020-05-20-makefile-escaping %} - -{% for feature in page.features %} - {{ feature.note | markdownify }} - {% for section in feature.sections %} -<div class="row"> - {% if section.do %} - {% if section.dont %}{% assign width = "6" %}{% else %}{% assign width = "12" %}{% endif %} - <div class="col-md-{{ width }}"> - {% for guide in section.do %} - <div class="pre_container pre_do"> - <pre>{{ guide }}</pre> - <div class="pre_mark"><span class="glyphicon glyphicon-ok"></span></div> - </div> - {% endfor %} - </div> - {% endif %} - {% if section.dont %} - {% if section.do %}{% assign width = "6" %}{% else %}{% assign width = "12" %}{% endif %} - <div class="col-md-{{ width }}"> - {% for guide in section.dont %} - <div class="pre_container pre_dont"> - <pre>{{ guide }}</pre> - <div class="pre_mark"><span class="glyphicon glyphicon-remove"></span></div> - </div> - {% endfor %} - </div> - {% endif %} -</div> - {% endfor %} - <hr/> -{% endfor %} diff --git a/_notes/markdown.md b/_notes/markdown.md deleted file mode 100644 index 39cbbd9..0000000 --- a/_notes/markdown.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: Markdown -subtitle: style guide ---- -* `diff`- and HTML-friendliness is valued over human-readability. -* Every sentence starts on a new line ("semantic newlines"). -* Lines are at most 79 characters long, not counting neither the carriage -return, nor the line feed characters. - * Not 80 characters, because when you display a 80-character line with a -line feed at the end in Windows' `cmd`, an extra empty line is added. -* No hanging indents in lists. - * Nested lists are indented with 4 spaces. - * No hanging indents in those also. - * Longer items wrap at 79 characters and continue from the leftmost -character column. -Additional sentences start there also. -* Prefer reference-style links over inline links. -Omit the second pair of brackets `[]` entirely where appropriate. -For example, [Google] is preferred over both [Google](https://ya.ru) and -[I'm feeling lucky][google] (see [this document's source]). -* First- and second-level headers are underlined with strings of `=` and `-`. -The number of `=`/`-` signs must be equal to the number of characters in the -header. -* File paths are enclosed in double quotes. -Environment variable names are enclosed in a pair of backticks (\`) unless it's -a part of a path. -Executable names are enclosed in a pair of backticks (\`) unless it's a part of -a path, a link or a header. -* Code blocks are indented with 4 spaces. - - Code blocks inside lists are indented according to the spec - (https://github.github.com/gfm/#list-items), i.e. the column of the first - non-whitespace character in the item + 4. - -* Don't mix fenced code blocks with indented code blocks in a single document. - -| In a table, | the first | row | is underlined. -| ----------- | --------- | ----- | -------------- -| Leftmost | vertical | lines | are required. -| Rightmost | vertical | lines | are omitted. -{: .table .table-bordered } - -[Google]: https://www.google.com/ -[this document's source]: https://raw.githubusercontent.com/{{ site.github.repository_nwo }}/gh-pages/{{ page.path }} |
