LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Blogs > rainbowsally
User Name
Password

Notices


Rate this Entry

Quick install/uninstall of glib debug version for tracing, or... just for the heck of it.

Posted 05-22-2015 at 03:59 PM by rainbowsally
Updated 05-22-2015 at 04:27 PM by rainbowsally (an afterthought)

Quick install/uninstall of glib debug version for tracing, or... just for the heck of it.

For the heck of it?

Yeah. I told yuh. This is Computer Mad Science. It doesn't have to make sense or to be useful. ;-) [Though it might very well be both.]

Today's wonderful experience in Computer Mad Science features:
  • A download and a teaser snippet.
  • This might be interesting for folks new to using C and/or looking for interesting powerful yet simple ideas and it produces a debug version of glib that can be traced with a good debugger (like kdbg). Think of it as a demo if you don't need the lib.
  • The code snippet is interesting because it suggests the possibility of a user controlled step-by-step process, like a 'wizard', to run shell commands but under the control of C which is more powerful/versatile, and predictable.

So. If you're interested in low level stuff (like what qsort does, for example... no it's nothing like bubble sort at all and it's very tricky)... here's a debug version of glib 2.42.1. Make and trace some of the files in the 'test' folder once you have the debug version installed.

http://rainbowsally.org/rainbowsally...-dbg-rs.tar.xz

Run 'steps' in safe '--show-me' mode first. You'll see what we're talking about before actually doing anything. And notice the 's'kip command, allowing you to override the default root shell in case you want to do the 'make install' manually rather than trusting the script.

And while you contemplate the download, here's the code for 'steps' and the steps.txt file that it reads in order to automate everything from unpacking the glib sources, to compiling and installing them, to converting them to a new.make[tm] package with an uninstaller that gets loaded into the the system in case you delete the build files but you want to get rid of the thing. ;-)

The main missing piece of the snippet is 'slist.c' which does bash-like file and pipe functions and a few other things better than bash and much more easily than typical C functions. Take a look.

file: tools/steps-src/src/steps.c
purpose: commandline runner for glib debug version (won't run w/o the d/load)
Code:
// main.c -- skeleton created by new.main

#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <ctype.h> // isdigit()
#include <stdlib.h> // system()
#include "slist.h"

void dbg(){} // for a non-moving breakpoint

#define streq(a, b) (strcmp(a, b) == 0)
#define VERSION_MAJOR 1
#define VERSION_MINOR 0

int usage(int errcode);
int print_version();

int /* errcode */ steps();
int /* errorcode */ show_me();

int main(int argc, char** argv)
{
  dbg();
  int err = 0;
  if(argc > 2) return usage(1);

  do
  {
    if(argc == 2)
    {
      err = 0;
      if(streq(argv[1], "--help")) { usage(0); break; }
      if(streq(argv[1], "--version")) { print_version(); break; }
      if(streq(argv[1], "--show-me")) { err = show_me(); break; }
      // else
      err = 1;
      fprintf(stderr, "Unknown switch/option %s\nTry the --help switch\n", argv[1]);
      return err;
    }
    // else

    err = steps();
  }while(0);

  return err;
}

int usage(int errcode)
{
#include "usage_str.dat"
  fprintf( errcode == 0 ? stdout : stderr, "%s", usage_str);
  return errcode;
}

int print_version()
{
  printf("Version %d.%d\n", VERSION_MAJOR, VERSION_MINOR);
  return 0;
}

////////////////////////////////////////

// returns 1 if user skipped this step
int prompt(char* s, char* cmd);

static int is_step(char* line)
{
  // #<digit>
  return
         (line[0] == '#')
      && isdigit(line[1]) ;
}
// This is probably misnamed.  Should be is_description() or something.
// In any case it returns true (1) if the line describes the next command
// to be executed when running 'armed' or just shown when running --show-me.
static int is_comment1(char* line)
{
  // #.. not digit and not hash
  return
      line[0] == '#'
      && line[1] != '#'
      && ! isdigit(line[1]);
}

int /* errcode */ steps()
{
  int err = 0;
  char* line;
  char* cmdline;
  int nlines;
  int skip_step = 0;
  char** cmds = slist_new();
  slist_fileRead(&cmds, "tools/steps.txt");
  nlines = slist_count(&cmds);
  do
  {
    if(nlines == 0)
    {
      fprintf(stderr, "Can't find or open 'steps.txt' in the tools folder");
      slist_delete(&cmds);
      err = 1;
      break;
    }

    //////////////////////////////////////
    // run through the steps.txt printing out
    // only lines with single hashes, executing
    // the others.

    for(int i = 0; i < nlines; i++)
    {
      line = slist_get(&cmds, i);
      if(is_step(line))
      {
        cmdline = slist_get(&cmds, i+1);
        printf("\n[ARMED]\n"); 
        skip_step = prompt(line, cmdline);
        i++;
        if(skip_step)
          printf("Skipping to next step...\n");
        else
          err = system(cmdline);
      }
      else if (is_comment1(line))
        printf("%s\n", line);

      if(err) break;
    }

  }while(0);
  if(err)
  {
    fprintf(stderr, "ERROR: Failed step: %s\n", cmdline);
    fprintf(stderr, "       You may still be able to fix this manually.\n"
                    "       See tools/steps.txt for clues\n");
  }
  // don't delete while cmdline is still needed
  slist_delete(&cmds);
  return err;
}


int show_me()
{
  int err = 0;
  char* line;
  char* cmdline;
  int nlines;
  char** cmds = slist_new();
  slist_fileRead(&cmds, "tools/steps.txt");
  nlines = slist_count(&cmds);
  do
  {
    if(nlines == 0)
    {
      fprintf(stderr, "Can't find or open 'steps.txt' in the tools folder");
      slist_delete(&cmds);
      err = 1;
      break;
    }

    //////////////////////////////////////
    // run through the steps.txt printing out
    // only lines with single hashes.

    printf("STEPS WILL *NOT* EXECUTE BELOW:\n");

    for(int i = 0; i < nlines; i++)
    {
      line = slist_get(&cmds, i);
      if(is_step(line))
      {
        cmdline = slist_get(&cmds, i+1);
        printf("\n[SHOW]\n"); prompt(line, cmdline);
        i++;
      }
      else if (is_comment1(line))
        printf("%s\n", line);
    }

  }while(0);
  slist_delete(&cmds);
  return err;
}

// returns '1' if user skpped the next step
int prompt(char* s, char* cmd)
{
  char response[256];
  char* p = s;
  while(*p == '#')
    p++;
  while(*p == ' ')
    p++;
  printf("  %s\n", p);
  printf("  cmd = %s\n", cmd);
  printf("  Press ENTER to continue, Ctrl-C to abort\n");
  p = fgets(response, 256, stdin);
  if(*p > ' ' && toupper(response[0]) == 'S')
    return 1;
  else 
    return 0;
}

And this text file is now a commandline 'wizard' program.

file: tools/steps.txt
purpose: descriptions and shell commands, preview with --show-me switch. Abort at any time.
Code:
## Tried to do this with bash, but no workie.  So let's do it with C - 32 bits
## This file is the shell source code run by 'steps'.
#1 The next step unpacks glib-2.0 in the build folder.
(cd build && tar xaf files.tar.xz)
#2 Next we configure using the 00.sh script in the build folder.
(cd build/files && sh 00.sh) 
#3 Next we compile glib.  This can take a few minutes.  Not bad tho.
(cd build/files && make) 
#4 Next we install glib as root.  *** Type 's[kip]' to skip this step ***
(cd build/files && su -c "make install") 
#5 And put 'set-dbg-paths.sub' in ~/bin (to turn on the right paths)
(mkdir ~/bin || true) && cp tools/set-dbg-paths.sub ~/bin
#6 Next we import the installed files into the new.make[tm] TREE
rm -rf TREE-bak && mv TREE TREE-bak && make import >/dev/null
#7 ...and set the sources relative to /opt/dbg/usr
mv TREE/opt/dbg/usr/* TREE && rm -r TREE/opt
#8 Next we create an installed uninstaller in case we lose the Makefiles.
make uninstaller >/dev/null && rm -rf TREE/uninstall && mv uninstall TREE
#9 Finally, we clean up the temp build files
(rm -rf TREE-bak && cd build/files && make clean)
#10 .. and check the installation using 'make status' in the current dir.
make status
#                        ( Uh... )
#                              \
#                               /////
#                              -=0 O=-
#                                .L.
# 
# We probably don't have the uninstaller installed yet, right?
# -----------------------------------------------------------------------
# Run 'sudo make uninstall' first then 'sudo make install' to get the 
# uninstaller installed along with the other stuff.
# 
# It's all quite quick from this point on.  And if you lose your sources 
# or delete the Makefile, you can uninstall ALL the files using the 
# script you'll find in /opt/dbg/usr/uninstall too.
# 
# -The Computer Mad Science Team. :-)
# -----------------------------------------------------------------------
And to make this tasty for all you Computer Mad Scientists, here's a TODO list! :-)

Have at it.

TODO: Add the "Skipping to next command" notice to the --show-me loop too so it acts more like the armed run.
TODO: Give it a 'help' prefix code like "#h' so it can can be used to do any steps that can be done from a command line.

-The Computer Mad Science Team.

:-)

PS. An afterthought. If you want to trace the tests files, 'make' them (and make semiclean) and use 'source set-dbg-paths.sub' so you can get all the way down to the lowest levels of glib.

You should be able to see all the fields in the seemingly simple structs such as 'channel' in your debugger.

.
Posted in Uncategorized
Views 1751 Comments 0
« Prev     Main     Next »
Total Comments 0

Comments

 

  



All times are GMT -5. The time now is 02:55 AM.

Main Menu
Advertisement
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration