Using C to get application information Topic is solved

This forum can be used to talk about general design strategies, new ideas and questions in general related to wxWidgets. If you feel your questions doesn't fit anywhere, put it here.
Post Reply
ChronoGraff
Knows some wx things
Knows some wx things
Posts: 42
Joined: Wed Apr 22, 2015 5:42 pm

Using C to get application information

Post by ChronoGraff » Sat May 13, 2017 10:09 pm

Maybe this isn't the correct place to post a C question, but!

I am struggling a little with trying to get information from - at runtime - the front application. (Mac OSX 10.11.6)

Code: Select all

FILE * lsappinfo = popen("lsappinfo info -only pid `lsappinfo front`", "r");
char buff[256];

while (fgets(buff, sizeof(buff), lsappinfo) != 0)
{
    process_name = buff;
    printf("PROCESS NAME: %s\n", process_name);
}

pclose(lsappinfo);
I then get the PID which I was hoping I could attach to and then grab information from.

I hope this explains my query. Thanks.

ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 3404
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Using C to get application information

Post by ONEEYEMAN » Mon May 15, 2017 4:03 pm

Hi,
What did you get instead? And if you run this command from the Terminal, what output it produces?

And usual things applies:
1. Version of wx?
2. How did you build wx? What configure options?

ChronoGraff
Knows some wx things
Knows some wx things
Posts: 42
Joined: Wed Apr 22, 2015 5:42 pm

Re: Using C to get application information

Post by ChronoGraff » Tue May 16, 2017 2:38 pm

Hi ONEEYEMAN,

I have the problem sorted. I managed to attach to the process but it was very heavy so I ditched that idea.

I do have another problem... never ending!

It's another C question though relating to memory. The callback function below is called on each result set from sqlite3 C api. The problem is;

when I create the list _restricted_words and add to it I lose the variable value as I must malloc() then copy the returned value. When not free'ing the allocated memory the expected behaviour is the values remain but in process creating a memory leak.

How can I copy the value from argv[restricted_col] to _str_copy and retain the values when callback function goes out of scope?? Have you, or anyone for that matter, encountered such a problem and found a solution?

Many thanks.

Code: Select all

int select_callback(void * not_used, int argc, char * argv[], char ** col_name)
{
    not_used = 0;
    const unsigned int restricted_col = 3;

    char * _str_copy = malloc(strlen(argv[restricted_col]) + 1);
    strncpy(_str_copy, argv[restricted_col], strlen(argv[restricted_col]) + 1);

    if (_restricted_words == NULL)
    {
        _restricted_words = list_create(_str_copy, NULL);
    }
    else
    {
        list_append(_restricted_words, _str_copy);
    }

    free(_str_copy);

    return 0;
}

ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 3404
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Using C to get application information

Post by ONEEYEMAN » Tue May 16, 2017 4:14 pm

Hi,
Are you calling select_callback() in a loop?
What happens inside list_create()? Just parsing _str_copy and moving the data into _restricted_words?

Also, which value is lost - _restricted_words or _str_copy?

Did you try running under memcheck to see where the leak occur?

Now, more generally - why do you use C? C++ is much more powerful and robust with the memory allocation/destruction...

Thank you.

ChronoGraff
Knows some wx things
Knows some wx things
Posts: 42
Joined: Wed Apr 22, 2015 5:42 pm

Re: Using C to get application information

Post by ChronoGraff » Tue May 16, 2017 5:36 pm

I need to use C as it's a daemon, unless of course I don't need to use C and can use C++ then I will of course switch, C is a pain in the butt.

Code: Select all

node_t * list_create(const char * value, node_t * next)
{
    node_t * node = (node_t *)malloc(sizeof(node_t));
    *node = (node_t) { NULL };

    if (node == NULL)
    {
        perror("Error malloc() failed");
        exit(EXIT_FAILURE);
    }

    node->value = value;
    node->next = next;

    return node;
}
select_callback is a callback for sqlite3

Code: Select all

sqlite3 * db;
char * err_msg;

int rc = sqlite3_open("/usr/local/var/db/chronograff.db", &db);

if (rc != SQLITE_OK)
{
    fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
    sqlite3_close(db);
    exit(EXIT_FAILURE);
}

const char * sql = "SELECT * FROM black_list WHERE constrained = 'command';";
rc = sqlite3_exec(db, sql, select_callback, 0, &err_msg);

if (rc != SQLITE_OK)
{

    sqlite3_free(err_msg);
    sqlite3_close(db);
    exit(EXIT_FAILURE);
}

// tcpdump -i any 'tcp port http or port https' | awk '{print $3}'

int listening_desc = 0;
if (listening_desc == 0)
{
    listening_desc = chrono_socket_listen(LISTENING_PORT);
    printf("listening.\n");
}
The value that is lost is _restricted_words. The memory leak isn't causing problems 'yet', but without free'ing the allocation it will of course when _restricted_words becomes bigger.

Hope this helps. I will look into C++ daemons too, I just assumed daemons must be written in C

ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 3404
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Using C to get application information

Post by ONEEYEMAN » Tue May 16, 2017 6:01 pm

Hi,
This is a very weird implementation of a linked list.
Why do you even need it as you use just one value there? Can't you just use _str_copy?

Or you just didn't post the parsing code?

Anyway LL is a double pointer implementation - one is for LL itself and one is for node.

You need to rewrite the code to use proper LL implementation.

Thank you.

ChronoGraff
Knows some wx things
Knows some wx things
Posts: 42
Joined: Wed Apr 22, 2015 5:42 pm

Re: Using C to get application information

Post by ChronoGraff » Tue May 16, 2017 6:15 pm

ONEEYEMAN wrote:Hi,
This is a very weird implementation of a linked list.
Why do you even need it as you use just one value there? Can't you just use _str_copy?

Or you just didn't post the parsing code?

Anyway LL is a double pointer implementation - one is for LL itself and one is for node.

You need to rewrite the code to use proper LL implementation.

Thank you.
I have a full library (my own one) for linked lists, the implementation is fine - it hasn't failed; there a lot more functions to work with it. The linked list is needed as the size is dynamic and using an array isn't going to allow me to do several things.

the lists header

Code: Select all

typedef struct node_ node_t;
struct node_
{
    const char * value;
    struct node_ * next;
};

typedef void (*list_event_cb_t)(node_t * head);
static void list_cb_register(list_event_cb_t * register_cb_func, node_t * head)
{
    (*register_cb_func)(head);
}

void list_traverse(node_t * head);
void list_display(node_t * head);
int list_count(node_t * head);
node_t * list_create(const char * value, node_t * head);
node_t * list_append(node_t * head, const char * value);
void list_remove_start(node_t * head);
void list_remove_end(node_t * head);
node_t * list_dispose(node_t * head);
There are 2 checks, I don't want to post the source as it's probably against rules here - I am not doing anything illegal, it's all for software to run on work machines.

When a user types every letter is collected (monitored), when you hit delete the program navigates the list and removes what was deleted. When using the arrow keys pressed etc. You get the idea? It's like a mirror of whatever the user is typing into the terminal and it's all checked at runtime and while it's being typed. So far there is no performance hit and it seems to run fine in the background.

When you hit space or enter the program checks against values that *the boss* can enter into a website portal (admin area); these are automatically updated into the daemon software but at the moment having a little issue with the strncpy() *what I've posted*.

The memory problem (I definitely don't want dangling pointers) is the only thing so far that is bothering me.

User avatar
doublemax
Moderator
Moderator
Posts: 13988
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Using C to get application information

Post by doublemax » Tue May 16, 2017 6:40 pm

I assume "_restricted_words" only stores pointers? In that case you must not free the memory that "_str_copy" points to. Instead you free it only when you destroy the list.
Use the source, Luke!

ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 3404
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Using C to get application information

Post by ONEEYEMAN » Tue May 16, 2017 6:48 pm

ChronoGraff,

Code: Select all

node_t * list_create(const char * value, node_t * next)
{
    node_t * node = (node_t *)malloc(sizeof(node_t));
    *node = (node_t) { NULL };

    if (node == NULL)
    {
        perror("Error malloc() failed");
        exit(EXIT_FAILURE);
    }

    node->value = value;
    node->next = next;
    return node;
}
In the code above, what is "node->value"?
You are doing a simple assignment, instead of shallow copy. Therefore when you are getting out the caller calls:

Code: Select all

free(_str_cpy);
And you memory goes bye-bye.

Thank you.

ChronoGraff
Knows some wx things
Knows some wx things
Posts: 42
Joined: Wed Apr 22, 2015 5:42 pm

Re: Using C to get application information

Post by ChronoGraff » Tue May 16, 2017 6:53 pm

doublemax wrote:I assume "_restricted_words" only stores pointers? In that case you must not free the memory that "_str_copy" points to. Instead you free it only when you destroy the list.
doublemax; It was suggested to use C++, it seems it's doable in C++. That's a shift though, but! What you just suggested will work, yes _restricted_words only stores pointers.

ONEEYEMAN; yes, it a simple assignment and that's exactly what is happening the memory is gone!

I can just delete/free _restricted_words and it will free the pointers?? I assume this to be correct. Excuse any ignorance, I have been scratching my head for almost 24 hrs.

ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 3404
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Using C to get application information

Post by ONEEYEMAN » Tue May 16, 2017 6:59 pm

ChronoGraff,
Nothing is automatic in C{++} world - this is not JAVA. ;-)
You will just need to move the "free()" statement to the end of the program when you will not needed anymore and possibly make the LL a global pointer.

ChronoGraff
Knows some wx things
Knows some wx things
Posts: 42
Joined: Wed Apr 22, 2015 5:42 pm

Re: Using C to get application information

Post by ChronoGraff » Tue May 16, 2017 7:05 pm

That's what I was thinking. I might leave it as C. It works so far so good.

Many thanks guys for the help.

User avatar
doublemax
Moderator
Moderator
Posts: 13988
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Using C to get application information

Post by doublemax » Tue May 16, 2017 7:40 pm

I can just delete/free _restricted_words and it will free the pointers?? I assume this to be correct. Excuse any ignorance, I have been scratching my head for almost 24 hrs.
No. "_restricted_words" doesn't know anything about what it stores. You have to iterate over all elements, free every pointer and then free the memory of the list itself.

Like ONEEYEMAN said, nothing is automatic in C. Every malloc() must have a matching free() with the exact pointer that malloc() returned. The only exception is when the documentation of a function explicitly states that it takes owner ship of a pointer that you may pass in as parameter. Or, if a function returns a pointer and the documentation says that the caller will take ownership and is responsible for freeing the memory.
Use the source, Luke!

Post Reply