Hi Bernard, 

Thanks for the reply. 

I'm using a source-based distro called SourceMage GNU Linux, which is what most 
of our productions servers are running. Various library versions follow: 

Ganglia-3.1.7
apr-1.3.9
confuse-2.7
procps-3.2.7

First, since you seem to be getting procps related errors, below is a small 
test program I wrote that uses procps to output the number of bash processes 
running on your system. This was the proof of concept from which the 
count_procs function in the module was derived, and it should confirm that the 
module's procps code is functional on your system.  I'd be curious to see if it 
compiles/runs for you.

Second, I wonder, did you add a 'ProcessNames' parameter to the module 
configuration in your gmond.conf?  I doubt, in it's current state, that this 
module will handle a NULL processNames variable gracefully. In fact, I'd fully 
expect it to crash and/or do other weird things since I'm calling strtok() on 
the processNames variable, without checking for nulls etc. The module 
configuration in gmond.conf should look something like the following (sorry, I 
should have mentioned that in my initial mail):

  module {
    name = "cp_module"
    path = "modcprocs.so"
    Param ProcessNames {
      Value = "httpd"
    }
  }


Finally, do you see anything obviously wrong with my use of apr_array_push?

Thanks again.

-dave


########### test_proc_counter.c ############
#include "<readproc.h>"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void enumerate_procs(char *proc_name) {

     int numprocs = 0;
     PROCTAB *proct;
     proc_t *proc_info;

     proct = openproc(PROC_FILLARG | PROC_FILLSTAT | PROC_FILLSTATUS);

     while ((proc_info = readproc(proct,NULL))) {
      if(!strncmp(proc_info->cmd,proc_name,sizeof(proc_info->cmd))){
       numprocs++;
      }
     }

     closeproc(proct);
     printf("%d\n",numprocs);
}

int main() {
     enumerate_procs("bash");
     return 0;
}

################## cc command I used ###################
cc -lproc-3.2.7 test.c

----- Original Message -----
From: "Bernard Li" <bern...@vanhpc.org>
To: "Dave Josephsen" <d...@dbg.com>
Cc: ganglia-general@lists.sourceforge.net
Sent: Friday, September 17, 2010 7:30:19 PM GMT -06:00 US/Canada Central
Subject: Re: [Ganglia-general] segfault in apr_array_push trying to write a new 
module

Hi Dave:

I was able to build on RHEL6b2 x86_64 and when I run gmond with the
module, I got a different error:

(gdb) r -d1
Starting program: /opt/ganglia.cprocs/sbin/gmond -d1
[Thread debugging using libthread_db enabled]

Program received signal SIGSEGV, Segmentation fault.
find_elf_note () at proc/sysinfo.c:195
195       while(*ep++);

I built with the following options:

gcc -fPIC mod_cpros.c -shared -I/usr/include/apr-1 -I../../../include
-I../../../lib -I/root/download.d/procps-3.2.8/proc/
-L/root/download.d/procps-3.2.8/proc -lproc-3.2.8 -o modcprocs.so

On a CentOS 4.4 i386 box I got yet another error:

(gdb) r -d1
Starting program: /opt/ganglia.cprocs/sbin/gmond -d1
[Thread debugging using libthread_db enabled]
[New Thread -1208416576 (LWP 5283)]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1208416576 (LWP 5283)]
0x00a2ab68 in uptime () from /root/download.d/procps-3.2.8/proc/libproc-3.2.8.so

Which distro/version did you compile on?

Thanks,

Bernard

On Fri, Sep 17, 2010 at 12:38 PM, Dave Josephsen <d...@dbg.com> wrote:
> Greetings list.
>
> I'm trying to write a gmond module in C that will count the number of named 
> processes running on the host. The full sourcecode of the module is pasted 
> below.
>
> The problem I'm running into is a segfault, which gdb says is occuring in 
> apr_array_push.  The idea behind this module is that the user will provide a 
> space-separated list of process names as a value to a parameter called 
> "ProcessNames" in the config file (something similar to Value = "httpd jsvc 
> bash").  Since there's no way of knowing how many processes the user might 
> provide, I need to grow the metric definition array dynamically, and that's 
> why I'm calling apr_array_push.  The module is segfaulting on my first call 
> to apr_array_push.
>
> I must admit that I don't know anything about the apr, I'm mostly just 
> following mod_gstatus.c as an example, so I don't have a good mental picture 
> of the data structures here. I see that apr_array_push has to do with apr's 
> dynamic array functionality, but I must be using it wrong somehow.  I was 
> hoping whatever I'm doing wrong might be glaringly obvious to someone on the 
> list. Any and all help is appreciated.
>
> Thanks in advance.
>
> -dave
>
>
> ##################  mod_cprocs.c source ##################
> /*******************************************************************************
> * This software is public domain. No rights reserved. Do whatever you want
> * (and leave me alone)
> *
> * Author: Dave Josephsen (dave at skeptech.org)
> ******************************************************************************/
>
> #include <gm_metric.h>
> #include <ganglia_priv.h>
> #include <apr_strings.h>
>
> #include <stdlib.h>
> #include <stdio.h>
> #include <strings.h>
> #include <string.h>
> #include <time.h>
> #include <readproc.h> // the readproc library from the linux procps project. 
> most systems don't have this installed by default
>
> extern mmodule cp_module;
> static apr_array_header_t *metric_info = NULL;
> char *processNames;
>
> g_val_t count_procs(char *proc_name) {
> //This function counts the number of instances of the given name (like 
> 'httpd' for example)
>
>   int numprocs=0;
>   PROCTAB *proct;
>   proc_t *proc_info;
>   g_val_t returnThis;
>
>   proct = openproc(PROC_FILLARG | PROC_FILLSTAT | PROC_FILLSTATUS);
>
>   while ((proc_info = readproc(proct,NULL))) {
>      if(!strncmp(proc_info->cmd,proc_name,sizeof(proc_info->cmd))){
>         numprocs++;
>      }
>   }
>   closeproc(proct);
>   returnThis.int32 = numprocs;
>   return returnThis;
> }
>
> static int cp_metric_init ( apr_pool_t *p )
> {
>    const char* str_params = cp_module.module_params;
>    apr_array_header_t *list_params = cp_module.module_params_list;
>    mmparam *params;
>    char processNamesCp[4242];
>    Ganglia_25metric *gmi;
>    char processDesc[1024];
>    int i;
>
>    srand(time(NULL)%99);
>
>    /* Read the parameters from the gmond.conf file. */
>    if (list_params) {
>        debug_msg("[mod_countproc] Received following params list: ");
>        params = (mmparam*) list_params->elts;
>        for(i=0; i< list_params->nelts; i++) {
>            debug_msg("\tParam: %s = %s", params[i].name, params[i].value);
>            if (!strcasecmp(params[i].name, "ProcessNames")) {
>                processNames = params[i].value;
>            }
>        }
>    }
>
>    // metadata storage
>
>    strncpy(processNamesCp, processNames,sizeof(processNames)); //avoid 
> allowing strtok to clobber the original ProcessNames string
>    char * processName = strtok(processNamesCp, " ");
>    for(i=0; processName != NULL; i++) {
>       gmi = apr_array_push(metric_info);
>       snprintf(processDesc,sizeof(processDesc)-1,"Number of %s 
> Processes",processName);
>       processDesc[sizeof(processDesc)-1]='\x0';
>
>       /* gmi->key will be automatically assigned by gmond */
>       gmi->name = apr_pstrdup (p, processName);
>       gmi->tmax = 512;
>       gmi->type = GANGLIA_VALUE_UNSIGNED_INT;
>       gmi->units = apr_pstrdup(p, "count");
>       gmi->slope = apr_pstrdup(p, "both");
>       gmi->fmt = apr_pstrdup(p, "%u");
>       gmi->msg_size = UDP_HEADER_SIZE+8;
>       gmi->desc = apr_pstrdup(p, processDesc);
>
>       MMETRIC_INIT_METADATA(gmi,p);
>       MMETRIC_ADD_METADATA(gmi,MGROUP,"pcount");
>
>       processName = strtok(NULL," ");
>    }
>
>    /* Add a terminator to the array and replace the empty static metric 
> definition
>        array with the dynamic array that we just created
>    */
>    gmi = apr_array_push(metric_info);
>    memset (gmi, 0, sizeof(*gmi));
>
>    cp_module.metrics_info = (Ganglia_25metric *)metric_info->elts;
>
>
>    return 0;
> }
>
> static void cp_metric_cleanup ( void )
> {
> }
>
> static g_val_t cp_metric_handler ( int metric_index )
> {
>    Ganglia_25metric *gmi = &(cp_module.metrics_info[metric_index]);
>    g_val_t val = count_procs(gmi->name);
>
>    return val;
> }
>
> mmodule cp_module =
> {
>    STD_MMODULE_STUFF,
>    cp_metric_init,
>    cp_metric_cleanup,
>    NULL, /* Dynanically defined in cp_metric_init() */
>    cp_metric_handler,
> };
>
>
>
> #################### GDB Output ####################
> d...@box:~/gmodules/ganglia-3.1.7/gmond/modules/cprocs# gdb /usr/sbin/gmond
> GNU gdb (GDB) 7.1
> <snip>
> Reading symbols from /usr/sbin/gmond...(no debugging symbols found)...done.
> (gdb) run -d1
> Starting program: /usr/sbin/gmond -d1
>
> Program received signal SIGSEGV, Segmentation fault.
> 0xb7f29ad6 in apr_array_push () from /usr/lib/libapr.so.0
>
>
> ################### GCC Syntax ##########################
> from the ganglia-3.1.7/gmond/modules/mymodule directory:
> cc mod_count_procs.c -shared -I/usr/include/proc -I/usr/include/apr/ 
> -I../../../include/ -I../../../lib -lproc-3.2.7 -o modcprocs.so
>
>
> ------------------------------------------------------------------------------
> Start uncovering the many advantages of virtual appliances
> and start using them to simplify application deployment and
> accelerate your shift to cloud computing.
> http://p.sf.net/sfu/novell-sfdev2dev
> _______________________________________________
> Ganglia-general mailing list
> Ganglia-general@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/ganglia-general
>

------------------------------------------------------------------------------
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing.
http://p.sf.net/sfu/novell-sfdev2dev
_______________________________________________
Ganglia-general mailing list
Ganglia-general@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ganglia-general

Reply via email to