Essential LLDB Commands

Below I list a set of essential lldb commands I regularly use. A more complete cheat sheet can be found here (direct link).

Compilation

Compile in Debug mode with the following additional flags:

-g -ggdb

Usage

Running

$ lldb Executable
(lldb) target create "Executable"
Current executable set to 'Executable' (x86_64).
(lldb) run [args]

Navigating a stack

  • Breakpoints
    b main
    breakpoint set --name main
  • Backtraces
    bt
    thread backtrace
    thread backtrace all
    • Frame information
      frame info
    • Navigate down
      down
      frame s -r-1
      frame select --relative=-1
    • Navigate up
      up
      frame s -r1
      frame select --relative=1
    • Select a frame
      f 3
      fr s 3
      frame select 3
  • Continue
    c
    thread continue
  • Step in
    s
    step
    thread step-in
  • Step over
    n
    next
    thread step-over
  • Step out
    finish
    thread step-out

Evaluating variables

  • Local variables
    frame variable
    fr v
  • Print the contents of a variable
    p var
    fr v var
    frame variable var

Printing values with C Format Strings

In order to ensure compiler and platform portability use the following rules for C format strings.

Assumption: A value of 16/32 or 64bit length needs to be printed with a C99 format string.

  • Until 16-bit length: use %d for signed and %u for unsigned. No casts are needed.
  • 32-bit length: use %ld for signed and %lu for unsigned. Cast to long or unsigned long, respectively.
  • 64-bit length: use %lld for signed and %llu for unsigned. Cast to long long or unsigned long long, respectively.
  • size_t: use %zu.
  • Hex:
    • Until 16-bit length use %x.
    • 32-bit length use %lx and cast to unsigned long.
    • 64-bit length use %llx and cast to unsigned long long.

Individual cases:

ValueFormat stringReason
char"%d"Is promoted to int.
short"%d"Is promoted to int. Minimal width: 16bit.
int%dMinimal width: 16bit (int16_t).
long%d or %ldMinimal width: 32bit (int32_t).
long long%lldMinimal width: 64bit (int64_t).
int8_t%dIs promoted to int.
int16_t%dIs promoted to int.
int32_t%ldCast to long required.
int64_t%lldCast to long long required.
unsigned char%dIs promoted to int
unsigned short%u
unsigned int%uMinimal width: 16bit (uint16_t)
unsigned long%luMinimal width: 32bit (uint32_t)
unsigned long long%lluMinimal width: 64bit (uint64_t)
uint8_t%u or %dIs promoted to int.
uint16_t%uIs promoted to int.
uint32_t%luCast to unsigned long required.
uint64_t%lluCast to unsigned long long required.
size_t%zu
float%f or %gPromoted to double for printing (compiler dependent).
double%f or %g
void *%p
hex(uint8_t)%x or %X
hex(uint16_t)%x or %X
hex(uint32_t)%lx or %lXCast to unsigned long required.
hex(uint64_t)%llx or %llXCast to unsigned long long required.

For more information see this manpage.

Docker Commands

Useful docker commands

Run interactive shell on an image

docker run \
    -it -e VAR_A=1 -e VAR_B=2 \
    -v $PWD:/mapped_volume \
    -w /workdir \
    ubuntu:18.04 /bin/bash

Dockerfile example

# Dockerfile
FROM ubuntu:18.04
ENV TZ=Europe/Zurich
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN dpkg --add-architecture i386 \
    && apt-get update \
    && apt-get install -y \
         build-essential \
         wget \
         curl \
         expect \
         sudo \
    && rm -rf /var/lib/apt/lists/*
RUN useradd -ms /bin/bash user

Build Dockerfile and tag it with the name “image”

docker build -t image -f Dockerfile .

Clear all stopped containers

docker rm $(docker ps -q -f 'status=exited')

Using Git Subtrees

With Git Subtrees it is possible to attach a remote git repository as a single commit to the repository.

  • A simple git clone will not download all the git submodules
  • Modifying code in a git submodule folder can be a nightmare, especially when the code should be comitted back to the origin

With Git Subtrees it is possible to attach a remote git repository as a single commit to the repository. To add a subproject as a git subtree, one would execute something like

git subtree add --prefix target_dir git_remote.git branch --squash

This will create a checkout of git_remote on branch in the target_dir.  And adds it to your current repository as a single commit (--squash) together with a merge commit:

commit f5ddddda7d42d06cd7883f7c495124f7dd4f503f
Merge: ed74e04 688ea1d
Author: Pascal <pascal@localhost>
Date:   Fri Sep 16 12:02:58 2016 +0200

Merge commit '688ea1de2af40776bfda21e59a14f97e6204e294' as 'foo'

commit 688ea1de2af40776bfda21e59a14f97e6204e294
Author: Pascal <pascal@localhost>
Date:   Fri Sep 16 12:02:58 2016 +0200

    Squashed 'target_directory/' content from commit 62372d7

    git-subtree-dir: target_directory
    git-subtree-split: 62372d78da03021a81c12972e483d3d074469be7

In order to update this subtree one can generally do

$git subtree pull --prefix target_directory git_remote.git branch --squash

which will add the updated code and will add it as a merge commit.

A possible use-case would be the management of static dependencies that are stored in a separate git repository. More information on git subtree can be found in this write here: https://developer.atlassian.com/blog/2015/05/the-power-of-git-subtree/

High Performance Computing at MeteoSwiss

From Mai 2015 to December 2017 I worked for MeteoSwiss and the Center for Climate Systems Modeling (C2SM). During this time I had the chance to work on the C++ Dynamical Core that runs the Swiss Weather model.

This scientific poster was published for the PASC 2017 conference and shows a summary of my work. The PDF is available here and additional information can be found on the C2SM Wiki.