Find DLL/SO of an Executable

On Linux

ldd

ldd – print shared library dependencies

$ cat hello.cpp
#include <iostream>
int main()
{
        std::cout << "Hello, world!" << std::endl;         return 0;
}
$ g++ -o hello hello.cpp $ ldd -v hello
        linux-vdso.so.1 =>  (0x00007fffb0bfd000)
        libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x0000003964a00000)
        libm.so.6 => /lib64/libm.so.6 (0x000000395e600000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000003964200000)
        libc.so.6 => /lib64/libc.so.6 (0x000000395e200000)
        /lib64/ld-linux-x86-64.so.2 (0x000000395de00000)

        Version information:
        ./hello:
                libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6
                libstdc++.so.6 (CXXABI_1.3) => /usr/lib64/libstdc++.so.6
                libstdc++.so.6 (GLIBCXX_3.4) => /usr/lib64/libstdc++.so.6
        /usr/lib64/libstdc++.so.6:
                ld-linux-x86-64.so.2 (GLIBC_2.3) => /lib64/ld-linux-x86-64.so.2
                libgcc_s.so.1 (GCC_4.2.0) => /lib64/libgcc_s.so.1
                libgcc_s.so.1 (GCC_3.3) => /lib64/libgcc_s.so.1
                libgcc_s.so.1 (GCC_3.0) => /lib64/libgcc_s.so.1
                libc.so.6 (GLIBC_2.3.2) => /lib64/libc.so.6
                libc.so.6 (GLIBC_2.4) => /lib64/libc.so.6
                libc.so.6 (GLIBC_2.3) => /lib64/libc.so.6
                libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6
        /lib64/libm.so.6:
                libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6
        /lib64/libgcc_s.so.1:
                libc.so.6 (GLIBC_2.4) => /lib64/libc.so.6
                libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6
        /lib64/libc.so.6:
                ld-linux-x86-64.so.2 (GLIBC_2.3) => /lib64/ld-linux-x86-64.so.2
                ld-linux-x86-64.so.2 (GLIBC_PRIVATE) => /lib64/ld-linux-x86-64.so.2

locate

locate – locate reads one or more databases prepared by updatedb(8) and writes file names matching at least one of the PATTERNs to standard output, one per line.

By default, locate does not check whether files found in database still exist; locate can never report files created after the most recent update of the relevant database.

Windows

Process Monitor

Process Monitor is an advanced monitoring tool for Windows that shows real-time file system, Registry and process/thread activity.

  • More data captured for operation input and output parameters
  • Non-destructive filters allow you to set filters without losing data
  • Capture of thread stacks for each operation make it possible in many cases to identify the root cause of an operation
  • Reliable capture of process details, including image path, command line, user and session ID
  • Configurable and moveable columns for any event property
  • Filters can be set for any data field, including fields not configured as columns
  • Advanced logging architecture scales to tens of millions of captured events and gigabytes of log data
  • Process tree tool shows relationship of all processes referenced in a trace
  • Native log format preserves all data for loading in a different Process Monitor instance
  • Process tooltip for easy viewing of process image information
  • Detail tooltip allows convenient access to formatted data that doesn’t fit in the column
  • Cancellable search
  • Boot time logging of all operations
Advertisements

Environment in Make

Following description is based on linux/bash. It is easy to switch to other platforms/shells.

Set Environment

There are two ways to set environment variables

export MYVAR=myvalue

the command sets the environment variable in current shell, the variable keep valid until it is deleted or changed and will be passed to all child processes by default.

MYVAR=myvalue command

This sets the environment variable for the command only (and it will be inherited by that process. It won’t change current shell environment.

We use this perl script to show a process environment

$ cat env.pl
#! /usr/bin/env perl

my $en = shift || 'MYVAR';
my $ev = $ENV{$en};
$ev = '' unless defined($ev);
print "$en=$ev\n";

Here is the result

$ ./env.pl
MYVAR=
$ export MYVAR=hello
$ echo $MYVAR
hello
$ ./env.pl
MYVAR=hello
$ unset MYVAR
$ echo $MYVAR

$ ./env.pl
MYVAR=
$ MYVAR=Hello ./env.pl
MYVAR=Hello
$ echo $MYVAR

$

Set Make Variable

Make variable can be set by environment (by setting before make), by command line (by setting after make), or set inside make file.

  1. both environment and command set initial variable value
  2. inside setting override environment value (unless -e is set for make)
  3. command line setting always overrides makefile setting (in other words, makefile setting can’t change command line settings)

Here is a makefile

$(info init value CC=$(CC), CXX=$(CXX))

CC :=gcc
CXX :=g++

all:
        @echo CC=$(CC) CXX=$(CXX)

The execute result is

$ CC=hello make
init value CC=hello, CXX=g++
CC=gcc CXX=g++
$ CC=hello make -e
init value CC=hello, CXX=g++
CC=hello CXX=g++
$ make CC=hello
init value CC=hello, CXX=g++
CC=hello CXX=g++
$ CC=hello make CXX=world
init value CC=hello, CXX=world
CC=gcc CXX=world
$

Misc in PostgresSQL

Sequence

A serial-type column in a table, e.g.

create table os (
  id                            serial,
  ...

it is actually defined as

postgres=> \d os
                         Table "public.os"
 Column | Type | Modifiers
---------+-------------+-------------------------------------------------
 id      | integer     | not null default nextval('os_id_seq'::regclass)
 ...

That is, a sequence named <table>_<column>_seq is created implicitly.

Sequence is guaranteed to advance every time nextval() is called, even the update is canceled by rollback. So “holes” might be left. It won’t skip existing values either (for example, suppose id is a unique key, and a value is inserted before the sequence reaches that value, a unique violation will occur when the sequence advanced to the value). The best practice is never set serial directly. In some special cases, such as restore/copy data, always call setval() after the data are copied.

Here are sequence functions

Function Return Type Description
currval(regclass) bigint Return value most recently obtained with nextval for specified sequence
lastval() bigint Return value most recently obtained with nextval for any sequence
nextval(regclass) bigint Advance sequence and return new value
setval(regclass, bigint) bigint Set sequence’s current value
setval(regclass, bigint, boolean) bigint Set sequence’s current value and is_called flag

See details at PostgreSQL Document 9.16. Sequence Manipulation Functions

 

Password File

In a trusted environment, accessing database with password can be eliminated with saved password file. On Posix systems, it is $HOME/.pgpass, on Windows, it is %APPDATA%\postgresql\pgpass.conf.

The file contains lines of following format:

hostname:port:database:username:password

except password, the first 4 fields can be *, which matches anything.

The permission of .pgpass should be stricter than 0600, otherwise the file will be ignored. However the permission of pgpass.conf is not checked on Windows.

Reference: PostgreSQL Manual: 31.15. The Password File

Errors and Messages

RAISE statement is used to report message and raise error in SQL/PLSQL

RAISE [ level ] 'format' [, expression [, ... ]] [ USING option = expression [, ... ] ];
RAISE [ level ] condition_name [ USING option = expression [, ... ] ];
RAISE [ level ] SQLSTATE 'sqlstate' [ USING option = expression [, ... ] ];
RAISE [ level ] USING option = expression [, ... ];
RAISE ;

level

  • DEBUG
  • LOG
  • NOTICE
  • WARNING
  • EXCEPTION (default, which aborts the current transaction))

‘format’

Must be a string literal (not an expression), followed by optional arguments to be inserted into the message, where % is replaced by the string representation of arguments.

USING option

  • MESSAGE
  • DETAIL
  • HINT
  • ERRCODE
  • COLUMN, CONSTRAINT, DATATYPE, TABLE, SCHEMA

Common Error Codes

  • 02000 – no_data_found
  • 22000 – data_exception
  • 23000 – integrity_constraint_violation
  • 40000 – transaction_rollback
  • 42000 – syntax_error_or_access_rule_violation

Note:

  • although the name of 02000 is “no_data” in all versions of manual, the actual is no_data_found

Please check the full error code list

Detect No Data in PL/SQL

Example 1 (not reliable)

declare
    pid int;
begin
    select id into pid
    from table_foo
    where name='foo';
    -- not reliable, e.g. the value of id is null
    if pid is null then
        raise no_data_found
        using detail=format('name %s is not found', 'foo');
    end if;
end;

Example 2

begin
    update build
    set state='start'
    where name='foo';
    if not found then
        raise no_data_found
        using detail=format('name %s is not found', 'foo');
    end if;
end;

Trapping Errors in PL/SQL

[ <> ]
[ DECLARE
      DECLARATIONS ]
BEGIN
    statements
EXCEPTION
    WHEN condition [ OR condition ... ] THEN
        handler_statements
   [WHEN condition [ OR condition ...] THEN
        handler_statements
    ...]
END;

Here is an example that traps error for SELECT … INTO STRICT var. INTO STRICT means there is EXACTLY one row retrieved

BEGIN
    SELECT * INTO STRICT myrec FROM emp WHERE empname = myname;
EXCEPTION
    WHEN NO_DATA_FOUND THEN
        RAISE EXCEPTION 'employee % not found', myname;
    WHEN TOO_MANY_ROWS THEN
        RAISE EXCEPTION 'employee % not unique', myname;
END;

Here are some examples of condition

WHEN division_by_zero THEN ...
WHEN SQLSTATE '22012' THEN ...

Parse Command Line arguments

Bash

#!/bin/bash
OPTIND=1           # reset in case getopts has been used previously
# default settings
output=""
verbose=0
while getopts "h?vf:" opt; do
    case "$opt" in
    h|\?)  show_help; exit 1;;
    v) verbose=1;;
    f) output=$OPTARG;;
    esac
done

shift $((OPTIND-1))
[ "$1" = "--" ] && shift;
echo "verbose=$verbose, output=$output, leftover: $@"

Reference:

Perl

#! /usr/bin/env perl

use strict;
use warnings;
use Getopt::Std;

sub usage {
    print "usage:\n".
          "$0 -hvf other_list\n".
          "  -h     help\n".
          "  -v     verbose\".
          "  -f file output file\n".
          "\n";
    exit 1;
}

my %opts;
my $rc = getopts('hvf:', \%opts);
usage() if ($rc || $opts{h});
print "options:\n";
print "$_: $opts{$_}\n" foreach (sort keys %opts);
print "leftovers: @ARGV\n";

Reference:

Python

#! /usr/bin/env python

import argparse

parser = argparse.ArgumentParser()
parser.ad_argument('-f', '--output_file', type=str,
                     default='my_output', help='output file name')
parser.add_argument('-v', '--verbose', action='store_true', help='verbose mode')
args = parser.parse_args()
if args.verbose:
    print 'verbose mode'
with open(args.output_file, 'w') as f:
    # do something
    pass

Reference:

C/C++

under construction

Set Hostname on Linux

Types of hostnames

The hostname can be configured as follows

  1. Static host name assigned by sysadmin. For example, “server1”, “wwwbox2”, or “server42.cyberciti.biz”.
  2. Transient/dynamic host name assigned by DHCP or mDNS server at run time.
  3. Pretty host name assigned by sysadmin/end-users and it is a free-form UTF8 host name for presentation to the user. For example, “Vivek’s netbook”.

hostnamectl command

Let us see how to use the hostnamectl command.

How do I see the host names?

$ hostnamectl
## OR ##
$ hostnamectl status

Sample outputs:

   Static hostname: centos-7-rc
         Icon name: computer
           Chassis: n/a
        Machine ID: b5470b10ccfd49ed8e4a3b0e953a53c3
           Boot ID: f79de79e2dac4670bddfe528e826b61f
    Virtualization: oracle
  Operating System: CentOS Linux 7 (Core)
       CPE OS Name: cpe:/o:centos:centos:7
            Kernel: Linux 3.10.0-229.1.2.el7.x86_64
      Architecture: x86_64

How do I set the host name?

The syntax is:

# hostnamectl set-hostname Your-New-Host-Name-Here
# hostnamectl set-hostname "Your New Host Name Here" --pretty
# hostnamectl set-hostname Your-New-Host-Name-Here --static
# hostnamectl set-hostname Your-New-Host-Name-Here --transient

To set host name to “R2-D2”, enter:

# hostnamectl set-hostname R2-D2

To set static host name to “server1.cyberciti.biz”, enter:

# hostnamectl set-hostname server1.cyberciti.biz --static

To set pretty host name to “Senator Padmé Amidala’s Laptop”, enter:

# hostnamectl set-hostname "Senator Padmé Amidala's Laptop" --pretty

To verify new settings, enter:

# hostnamectl status

Sample outputs:

   Static hostname: server1.cyberciti.biz
   Pretty hostname: Senator Padmé Amidala's Laptop
Transient hostname: r2-d2
         Icon name: computer
           Chassis: n/a
        Machine ID: b5470b10ccfd49ed8e4a3b0e953a53c3
           Boot ID: f79de79e2dac4670bddfe528e826b61f
    Virtualization: oracle
  Operating System: CentOS Linux 7 (Core)
       CPE OS Name: cpe:/o:centos:centos:7
            Kernel: Linux 3.10.0-229.1.2.el7.x86_64
      Architecture: x86_64

How do I delete a particular host name?

The syntax is:

# hostnamectl set-hostname ""
# hostnamectl set-hostname "" --static
# hostnamectl set-hostname "" --pretty

How do I change host name remotely?

Use any one of the following syntax:

# ssh root@server-ip-here hostnamectl set-hostname server1

OR set server1 as host name on a remote server called 192.168.1.42 using ssh:

# hostnamectl set-hostname server1 -H root@192.168.1.42

 

 

 

Reference

 

Note:

  • hostnamectl exists on RHEL/Centos7, Debian8 (validated)

 

Some topics in SSH

Login SSH without typing password every time

  1. create public and private keys on local-host (debian)
    jason@debian$ ssh-keygen
    Generating public/private rsa key pair.
    Enter file in which to save the key (/home/jason/.ssh/id_rsa):[Enter key]
    Enter passphrase (empty for no passphrase): [Press enter key]
    Enter same passphrase again: [Pess enter key]
    Your identification has been saved in /home/jason/.ssh/id_rsa.
    Your public key has been saved in /home/jason/.ssh/id_rsa.pub.
    The key fingerprint is:
    33:b3:fe:af:95:95:18:11:31:d5:de:96:2f:f2:35:f9 jason@debian
    

    This command creates two RSA key files, id_rsa for private key, and id_rsa.pub for public key, in the directory $HOME/.ssh.

  2. copy the public key file to remote-host (fedora) using ssh-copy-id
    jason@debian$ ssh-copy-id -i ~/.ssh/id_rsa.pub fedora
    jason@fedora's password:
    jason@fedora$
    

    Now try logging into the remote machine (fedora)

    jason@debina$ ssh fedora
    Last login: Thu Feb 16 11:45:20 2017 from debian
    jason@fedora$
    

    Notice that ssh does not ask for password. Check the authorized_key to make sure we haven’t added extra keys that you weren’t expecting.

    jason@fedora$ cat .ssh/authorized_keys
    

ref – 3 Steps to Perform SSH Login Without Password Using ssh-keygen & ssh-copy-id
In case ssh-copy-id is not available (for example, on mingw), as an alternated solution, you can manually copy the public key file (id_rsa.pub) to the remote host, and add the content as a record into $HOME/.ssh/authorized_keys. The file is a text file, so if it doesn’t exist, you can create it with a text editor. Don’t forget to change the mode to 644, otherwise sshd won’t use it.

Define host aliases in SSH config

Following lines in ~/.ssh/config define two aliases for the host staging.example.com

host foo bar # aliases separated by whites
  hostname staging.example.com

ref – Defining host aliases in your SSH config