Monday, May 9, 2016

Using DBX Debugger on AIX -- How to pass program arguments to DBX

DBX is the default debugger in IBM AIX OS. This debugger's user interface is rather unusual compared to other debugger. It is a command line debugger just like GNU GDB. But, it has a different philosophy. The user guide for DBX is at: https://www.ibm.com/support/knowledgecenter/ssw_aix_61/com.ibm.aix.cmds2/dbx.htm. The user guide is exhaustive to be read all at once. I recommend you to focus on your goal, i.e. debugging requirements and read the user guide to suite the requirements.

Let's start with a basic requirements:

  • You have a command line program 
  • The program has several arguments that must be passed at startup time.
Now, let's look at the steps to fulfill the requirements above. Let's start with DBX philosophy. The DBX philosophy is as follows:

  1. Running dbx without any arguments in the shell only starts the debugging environment, nothing more, nothing less.
  2. Running dbx with only the executable (program) file name will load the executable into memory but doesn't run the program. This step also doesn't pass any argument(s) to the program.  
  3. DBX has the so-called "subcommands" which are "commands" that you can type in the DBX debugging environment to instruct the debugger to do something. Another way to pass subcommand to DBX is via a text file known as "command file". A command file contains subcommand and the parameters/arguments required by the subcommand.

The gist of the philosophy is: useful thing can be done mostly via DBX subcommands. The following diagram illustrates this philosophy.
Figure 1 IBM AIX DBX debugger principle of working
The DBX Command Line Interface (CLI) is similar to GNU GDB. Therefore, I'm not going to explain it here. I'll proceed to DBX Scripting Interface. The scripting interface is invoked via DBX's "-c" flag. This is the excerpt from DBX user guide:
-c CommandFileRuns the dbx subcommands in the file before reading from standard input. The specified file in the $HOME directory is processed first; then the file in the current directory is processed. The command file in the current directory overrides the command file in the $HOME directory. If the specified file does not exist in either the $HOME directory or the current directory, a warning message is displayed. The source subcommand can be used once the dbx program is started.
I'll show you how to use -c flag to pass your program arguments at the start of a DBX debugging session. The first thing to do before we can use -c flag is to prepare the Command File. If you just want to pass your program arguments, then the contents of the command file is simply the run subcommand and your program arguments. Below is an example of a valid Command File. Let's name the command file as my_cmd.
run -a 10.10.10.254 -p 8000 -n 2  
In the command file above, the program (to be debugged) arguments starts at -a, the run statement in the beginning refers to DBX run subcommand. The following diagram shows this:
Figure 2 Using run subcommand in your command file
This is the verbatim explanation for run subcommand  from DBX user guide:
run Subcommand
run [ Arguments ] [ <File ] [ >File ] [ > >File ] [ 2>File ] [ 2> >File ] [ >&File ] [ > >&File ]
The run subcommand starts the object file. The Arguments are passed as command-line arguments.
Flags
ItemDescription
<FileRedirects input so that input is received fromFile.
>FileRedirects output to File.
2>FileRedirects standard error to File.
> >FileAppends redirected output to File.
2> >FileAppends redirected standard error to File.
>&FileRedirects output and standard error to File.
> >&FileAppends output and standard error to File.
Example
To run the application with the arguments blue and 12, enter:
run blue 12

Therefore, to start DBX debugger to use my_cmd command file above, we enter this in the shell:
$ dbx -c my_cmd [your_program_name]
The -c flag instruct dbx to use my_cmd as the command file, after that you just need to enter your program executable name. Anyway, after dbx parses the command file, it runs your program as if you type run subcommand in a DBX debugging session.

That's it. I hope this post helps those who just started using DBX in AIX or other AIX-like environment.

Thursday, April 21, 2016

Blank Character is Not Null Character

Perhaps, it is partly because I'm not a native English speaker and partly because I forgot that the devil is in the details that I inadvertently wrote code that supposed to initialize a variable with blank characters with null characters.

Blank characters refer to whitespace character (https://en.wikipedia.org/wiki/Whitespace_character), not the null character (https://en.wikipedia.org/wiki/Null_character). In many cases, acceptable blank character for program input is space, which has a value of 20h in ASCII and 40h in EBCDIC. Well, this is not obvious for me at first until I'm debugging some code in an EBCDIC environment. 

So, next time you read an API documentation that says *BLANK*, it doesn't refer to NULL ('\0') character, but it refers to one of the whitespace character which in many cases refer to SPACE (' ').

As a bonus, these are some usable character conversion tables:
http://www.astrodigital.org/digital/ebcdic.html (this one explicitly states SPACE character as BLANK)

Sunday, March 20, 2016

[How-to] Copy Contents of Tmux Pane to File

There are many cases where you might want to copy part of (or the entire) contents of a tmux pane into file for further usage. This post explains how to that. Before we proceed, you need to be aware that my tmux key binding is probably different from yours, see: http://darmawan-salihun.blogspot.co.id/2015/02/zsh-tmux-configuration-for-arch-linux.html. I'm using vi mode-keys.

The steps to copy contents of a tmux pane are as follows:
  1. Enter copy mode. The key combo to enter copy mode depends on your tmux configuration, but the principle never change: press your tmux prefix key combo--in my case, this is Ctrl+A--and then press your tmux copy mode key-in my case the key is Escape. If you look at my tmux configuration file linked above, I should press: Ctrl+A, then Escape to enter tmux copy mode
  2. Select the text that you want to copy. I'm using the v key to select the text because that's how my tmux key binding is configured (~/.tmux.conf: bind -t vi-copy 'v' begin-selection). This is how it looks like once I have selected some text in copy mode with vi-like keys (the selected text is in yellow background):
    tmux copy mode
  3. Copy the selected text into tmux buffer. I'm using y (yank) key to select the text because that's how my tmux key binding is configured (~/.tmux.conf: bind -t vi-copy 'y' copy-selection). Now the selected text is in tmux buffer.
You can "save" contents of the tmux buffer to a file with this command:
$ tmux save-buffer -b [the_buffer_yo_want_to_save] -a [name_of_the_file_you_want_to_append_the_buffer_to]
If you want to just overwrite the contents of the "target" file with the tmux buffer contents, you can omit the -a flag. You can select your "source" tmux buffer before saving the tmux buffer contents by using the command completion key in your shell (in my case TAB -- I'm using zsh). Tmux buffer possibly contains more than one buffer if you previously "copy" something into the buffer, either inadvertently or on-purpose. This is how tmux buffer looks like in my shell as I'm trying to save one of its entries:
Tmux "copy buffer" number 0 to number 10

Anyway, you can also bind keys to the tmux save buffer command in order to make the text available for GUI application as in my tmux.conf shown in the link above. This is the configuration snippet (I'm using icccm clipboard for that):
# extra commands for interacting with the ICCCM clipboard
bind C-c run "tmux save-buffer - | xclip -i -sel clipboard"
bind C-v run "tmux set-buffer \"$(xclip -o -sel clipboard)\"; tmux paste-buffer"
That's it. I hope the explanation is clear enough because there are many explanation on the web that's not quite well-suited for newbie.

Thursday, February 18, 2016

C Macro 101: Stringizing Operator and Token Pasting Operator

Present day C language has evolved to the point where we can be productive writing code in it. Perhaps, many still views that writing code in C is tedious compared to writing code in other higher-level language. I think, that's a subjective view. Perhaps, only functional languages have higher productivity compared to C for most non-system-programming.

Two of the "productivity features" in C that I found indispensable at the moment are the stringizing operator (#) and token-pasting operator (a.k.a concatenation operator) (##). Both of these operators can be used in C macros only, you cannot use it outside of C macros. However, both are very powerful tools to create function templates in C. Yes, you read that right. Function templates are not just for C++ programmers. C programmers also has a sort of function template via C macros, despite it's a little "rudimentary" compared to C++.

Most stringizing and token-pasting tutorials out there don't provide useful code snippets with regard to the "real" power of these operators. This post aims to fill that gap. Without further ado, let's get to the code. You can clone the complete sample code used in this post from https://github.com/pinczakko/sample_token_pasting
#include <stdio.h>
#include <assert.h>

typedef enum {
 PEEK_REQUEST_ITEM,
 PEEK_REPLY_ITEM,
 MOD_REQUEST_ITEM,
 MOD_REPLY_ITEM
}ITEM_TYPE;

struct queue_item {
 ITEM_TYPE type;
 char payload[32];
};

struct handler {
 int identifier;
 int (*process_data) (void* data);
};

#define PRINT_FUNC_NAME \
do { \
 printf("In function: %s() \n", __func__); \
} while (0);

static inline int process_peek_request(const struct queue_item *const
          peek_req,
          struct handler *p)
{
 /** Algorithm A ...  */
 PRINT_FUNC_NAME
 return 0;
}

static inline int process_peek_reply(const struct queue_item *const
        peek_rep,
        struct handler *p)
{
 /** Algorithm B ...  */
 PRINT_FUNC_NAME
 return 0;
}

static inline int process_modification_request(const struct queue_item *const
          modification_req,
          struct handler *p)
{
 /** TODO: Invalidate cached items taking part in the MOD transaction **/

 /** TODO: Enqueue the MOD request to egress_port_output_queue */

 /** TODO: Notify egress_port thread to consume the MOD request */

 PRINT_FUNC_NAME

 return 0;/** Success */

 error:
 return -1;/** Failed */
}

static inline int process_modification_reply(const struct queue_item *const
        modification_rep,
        struct handler *p)
{
 /** TODO: Enqueue the MOD reply to ingress_port_output_queue */

 /** TODO: Notify ingress_port thread to consume the MOD reply */

 PRINT_FUNC_NAME

 return 0;/** Success */

 error:
 return -1;/** Failed */
}

#define PROCESS_DEQUEUED_ITEM(MESSAGE, TYPE) \
static inline int process_dequeued_##MESSAGE(const struct queue_item *const MESSAGE,\
         struct handler *p) \
{ \
 assert((MESSAGE != NULL) && (p != NULL)); \
 \
 assert((MESSAGE->type == PEEK_##TYPE) || \
        (MESSAGE->type == MOD_##TYPE)); \
 \
 PRINT_FUNC_NAME \
 \
 if (MESSAGE->type == PEEK_##TYPE) { \
  printf("Processing PEEK " #MESSAGE "\n"); \
  return process_peek_##MESSAGE(MESSAGE, p); \
 \
 } else if (MESSAGE->type == MOD_##TYPE) { \
  printf("Processing MOD " #MESSAGE "\n"); \
  return process_modification_##MESSAGE(MESSAGE, p); \
 \
 } else { \
  printf("Warning: Unknown " #MESSAGE " type!\n"); \
  return -1; /** Failed */ \
 } \
}

/** Token-pasted function instance to handle request message */
PROCESS_DEQUEUED_ITEM(request, REQUEST_ITEM)

/** Token-pasted function instance to handle reply message */
PROCESS_DEQUEUED_ITEM(reply, REPLY_ITEM)

int main (int argc, char * argv[])
{
 int i; 

 struct queue_item req_item[2], rep_item[2];
 struct handler h;

 req_item[0].type = PEEK_REQUEST_ITEM;
 req_item[1].type = MOD_REQUEST_ITEM;

 rep_item[0].type = PEEK_REPLY_ITEM;
 rep_item[1].type = MOD_REPLY_ITEM;

 for (i = 0; i < 2; i++) {
  process_dequeued_request(&req_item[i], &h);
 }

 for (i = 0; i < 2; i++) {
  process_dequeued_reply(&rep_item[i], &h);
 }

 return 0;
}
The code above will produce two different functions,  process_dequeued_request() and process_dequeued_reply(), respectively, to  handle request and reply. The algorithm used by both functions is very similar, the differences are only in function naming, parameters naming and constant naming. Therefore, it is natural to use token-pasting and stringizing operators in the code. In C++, you would use  C++ template. You can achieve the same thing in C with token-pasting (##) and stringizing operator (#).

The stringizing operator (#) basically creates a C string from the C macro parameter. For example, if you pass reply as parameter to a C macro, the C preprocessor will produce "reply" (C string -- including the double quotes) as output if the stringizing operator is applied to the macro parameter. Perhaps, it's a bit hard to understand. Let's look at the sample code above. In this line:
PROCESS_DEQUEUED_ITEM(reply, REPLY_ITEM)
we asked the preprocessor to instantiate the process_dequeued_reply() function. In the process_dequeued_reply() function, the code uses the stringizing operator like so:
printf("Processing PEEK " #MESSAGE "\n");
After GCC preprocessing stage, this function call becomes:
printf("Processing PEEK " "reply" "\n");
As you see, the reply macro input parameter is transformed into "reply", i.e. stringized.
Perhaps, you asked, how can I obtain the preprocessor output? Well, in most compiler, you can obtain the preprocessor output via certain compiler switch(es). In GCC, you can use the -save-temps switch to do so. The GCC preprocessor output is a *.i file with the same name as the source file. In my sample code, the Makefile uses this switch to instruct GCC to place the preprocessor output in the source code directory. I used the indent utility (indent -linux sample_token_pasting.i) to beautify the preprocessor output.
This is an example snippet of the "beautified" preprocessor output from sample_token_pasting.i file:
static inline int process_dequeued_reply(const struct queue_item *const reply,
      struct handler *p)
{
#107 "sample_token_pasting.c" 3 4
 ((
#107 "sample_token_pasting.c"
   (reply !=
#107 "sample_token_pasting.c" 3 4
    ((void *)0)
#107 "sample_token_pasting.c"
   ) && (p !=
#107 "sample_token_pasting.c" 3 4
         ((void *)0)
#107 "sample_token_pasting.c"
   )
#107 "sample_token_pasting.c" 3 4
  )? (void)(0) : __assert_fail(
#107 "sample_token_pasting.c"
          "(reply != ((void *)0)) && (p != ((void *)0))"
#107 "sample_token_pasting.c" 3 4
          , "sample_token_pasting.c", 107,
          __PRETTY_FUNCTION__))
#107 "sample_token_pasting.c"
     ;
#107 "sample_token_pasting.c" 3 4
 ((
#107 "sample_token_pasting.c"
   (reply->type == PEEK_REPLY_ITEM)
   || (reply->type == MOD_REPLY_ITEM)
#107 "sample_token_pasting.c" 3 4
  )? (void)(0) : __assert_fail(
#107 "sample_token_pasting.c"
          "(reply->type == PEEK_REPLY_ITEM) || (reply->type == MOD_REPLY_ITEM)"
#107 "sample_token_pasting.c" 3 4
          , "sample_token_pasting.c", 107,
          __PRETTY_FUNCTION__))
#107 "sample_token_pasting.c"
     ;
 do {
  printf("In function: %s() \n", __func__);
 } while (0);
 if (reply->type == PEEK_REPLY_ITEM) {
  printf("Processing PEEK " "reply" "\n");
  return process_peek_reply(reply, p);
 } else if (reply->type == MOD_REPLY_ITEM) {
  printf("Processing MOD " "reply" "\n");
  return process_modification_reply(reply, p);
 } else {
  printf("Warning: Unknown " "reply" " type!\n");
  return -1;
 }
}
It's a bit unwieldy. However, sometimes you need to be sure that you don't make any silly mistake with your C macro by looking into the preprocessor output.

Let's move to the other operator, the token-pasting operator. This operator basically "paste and concatenate" the macro parameter to create the "target" C token from both the macro parameter and the C token "fragment" in your macro. If you don't truly understand what a C language token yet, please read http://www.help2engg.com/c_tokens and https://msdn.microsoft.com/en-us/library/c6sb2c6b.aspx. The sample code uses the token-pasting operator to create "configurable" C function name and constants. This code:
PROCESS_DEQUEUED_ITEM(reply, REPLY_ITEM)
produces three C tokens: process_dequeued_reply function name, PEEK_REPLY_ITEM constant and MOD_REPLY_ITEM constant. You can see the process clearly in the GCC preprocessor output snippet above. The process_dequeued_ C token "fragment" is concatenated with the value of the MESSAGE macro parameter, which in this macro invocation:
PROCESS_DEQUEUED_ITEM(reply, REPLY_ITEM)
has a value equal to reply. Therefore, the concatenated ("target") C token is process_dequeued_reply. The constants also undergo similar transformation via the TYPE macro parameter.

Anyway, this is the output of the program (compiled from the sample code)
In function: process_dequeued_request() 
Processing PEEK request
In function: process_peek_request() 
In function: process_dequeued_request() 
Processing MOD request
In function: process_modification_request() 
In function: process_dequeued_reply() 
Processing PEEK reply
In function: process_peek_reply() 
In function: process_dequeued_reply() 
Processing MOD reply
In function: process_modification_reply() 
Well, the output just shows which functions are invoked and their order of invocation to clarify the inner working of both stringizing operator and token-pasting operator.

Hopefully, the explanation in this post clarify the power of C stringizing and token-pasting operator.