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" <[email protected]>
To: "Dave Josephsen" <[email protected]>
Cc: [email protected]
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 <[email protected]> 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
> [email protected]
> 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
[email protected]
https://lists.sourceforge.net/lists/listinfo/ganglia-general