-
Executing a program
HI
I have problems with executing memtester from another program.
I'm using Public release version of memtester and I added it to a menu, so that one of the test is memory test and you just press the enter button and memtester starts. Mmemtester starts and outputs an error
Code:
pagesize is 4096
pagesizemask is 0xfffff000
bytes < pagesize -- memory argument too large?
When you manually start a program you have to type 2 arguments, first is for amount of memory to test and secon how many times to test, it looks like this:
./memtester 950 1
I wanted that memtester finds the max amount of free memory to test so for the second argument I typed:
`free -om | grep 'Mem:' | awk '{print $4}'`
so the starting of the program looks like:
./memtester `free -om | grep 'Mem:' | awk '{print $4}'`1
So this works ok without a problem.
I have a problem with starting this from a menu(another program).
It works fine if I type allready the amount of memory into the first argument(not that he finds the number himself), but if I enter: `free -om | grep 'Mem:' | awk '{print $4}'`
into the first argument I get the pagesize error I mentioned before. What could be wrong? I use execvp for executing the program.
Memtester is from charles cazabom(wery known memtester) - I'm on linux platform, but I think that doesn't matter.
Have a nice Day
Matt
-
Well `` and | are interpreted by the shell, so depening on what you've done (I see you failed to post any code), you could just be passing the address of a string to the program, and it tries to interpret that as a number.
-
Code:
/*
* memtester version 4
*
* Very simple but very effective user-space memory tester.
* Originally by Simon Kirby <[email protected]> <[email protected]>
* Version 2 by Charles Cazabon <[email protected]>
* Version 3 not publicly released.
* Version 4 rewrite:
* Copyright (C) 2005 Charles Cazabon <[email protected]>
* Licensed under the terms of the GNU General Public License version 2 (only).
* See the file COPYING for details.
*
*/
#define __version__ "4.0.5"
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <unistd.h>
#include <errno.h>
#include "types.h"
#include "sizes.h"
#include "tests.h"
#define EXIT_FAIL_NONSTARTER 0x01
#define EXIT_FAIL_ADDRESSLINES 0x02
#define EXIT_FAIL_OTHERTEST 0x04
struct test tests[] = {
{ "Random Value", test_random_value },
{ "Compare XOR", test_xor_comparison },
{ "Compare SUB", test_sub_comparison },
{ "Compare MUL", test_mul_comparison },
{ "Compare DIV",test_div_comparison },
{ "Compare OR", test_or_comparison },
{ "Compare AND", test_and_comparison },
{ "Sequential Increment", test_seqinc_comparison },
{ "Solid Bits", test_solidbits_comparison },
{ "Block Sequential", test_blockseq_comparison },
{ "Checkerboard", test_checkerboard_comparison },
{ "Bit Spread", test_bitspread_comparison },
{ "Bit Flip", test_bitflip_comparison },
{ "Walking Ones", test_walkbits1_comparison },
{ "Walking Zeroes", test_walkbits0_comparison },
{ NULL, NULL }
};
#ifdef _SC_VERSION
void check_posix_system(void) {
if (sysconf(_SC_VERSION) < 198808L) {
fprintf(stderr, "A POSIX system is required. Don't be surprised if "
"this craps out.\n");
fprintf(stderr, "_SC_VERSION is %lu\n", sysconf(_SC_VERSION));
}
}
#else
#define check_posix_system()
#endif
#ifdef _SC_PAGE_SIZE
int memtester_pagesize(void) {
int pagesize = sysconf(_SC_PAGE_SIZE);
if (pagesize == -1) {
perror("get page size failed");
exit(EXIT_FAIL_NONSTARTER);
}
printf("pagesize is %ld\n", pagesize);
return pagesize;
}
#else
int memtester_pagesize(void) {
printf("sysconf(_SC_PAGE_SIZE) not supported; using pagesize of 8192\n");
return 8192;
}
#endif
int main(int argc, char **argv) {
ul loops, loop, i;
size_t pagesize, wantmb, wantbytes, wantbytes_orig, bufsize, halflen, count;
ptrdiff_t pagesizemask;
void volatile *buf, *aligned;
ulv *bufa, *bufb;
int do_mlock = 1, done_mem = 0;
int exit_code = 0;
printf("memtester version " __version__ " (%d-bit)\n", UL_LEN);
printf("Copyright (C) 2005 Charles Cazabon.\n");
printf("Licensed under the GNU General Public License version 2 (only).\n");
printf("\n");
check_posix_system();
pagesize = memtester_pagesize();
pagesizemask = (ptrdiff_t) ~(pagesize - 1);
printf("pagesizemask is 0x%tx\n", pagesizemask);
if (argc < 2) {
fprintf(stderr, "need memory argument, in MB\n");
exit(EXIT_FAIL_NONSTARTER);
}
wantmb = (size_t) strtoul(argv[1], NULL, 0);
wantbytes_orig = wantbytes = (size_t) (wantmb << 20);
if (wantbytes < pagesize) {
fprintf(stderr, "bytes < pagesize -- memory argument too large?\n");
exit(EXIT_FAIL_NONSTARTER);
}
if (argc < 3) {
loops = 0;
} else {
loops = strtoul(argv[2], NULL, 0);
}
printf("want %lluMB (%llu bytes)\n", (ull) wantmb, (ull) wantbytes);
buf = NULL;
while (!done_mem) {
while (!buf && wantbytes) {
buf = (void volatile *) malloc(wantbytes);
if (!buf) wantbytes -= pagesize;
}
bufsize = wantbytes;
printf("got %lluMB (%llu bytes)", (ull) wantbytes >> 20,
(ull) wantbytes);
fflush(stdout);
if (do_mlock) {
printf(", trying mlock ...");
fflush(stdout);
if ((size_t) buf % pagesize) {
/* printf("aligning to page\n"); */
aligned = (void volatile *) ((size_t) buf & pagesizemask);
bufsize -= ((size_t) aligned - (size_t) buf);
} else {
aligned = buf;
}
/* Try memlock */
if (mlock((void *) aligned, bufsize) < 0) {
switch(errno) {
case ENOMEM:
printf("too many pages, reducing...\n");
free((void *) buf);
buf = NULL;
wantbytes -= pagesize;
break;
case EPERM:
printf("insufficient permission.\n");
printf("Trying again, unlocked:\n");
do_mlock = 0;
free((void *) buf);
buf = NULL;
wantbytes = wantbytes_orig;
break;
default:
printf("failed for unknown reason.\n");
do_mlock = 0;
done_mem = 1;
}
} else {
printf("locked.\n");
done_mem = 1;
}
} else {
done_mem = 1;
printf("\n");
}
}
if (!do_mlock) fprintf(stderr, "Continuing with unlocked memory; testing "
"will be slower and less reliable.\n");
halflen = bufsize / 2;
count = halflen / sizeof(ul);
bufa = (ulv *) aligned;
bufb = (ulv *) ((size_t) aligned + halflen);
for(loop=1; ((!loops) || loop <= loops); loop++) {
printf("Loop %lu", loop);
if (loops) {
printf("/%lu", loops);
}
printf(":\n");
printf(" %-20s: ", "Stuck Address");
fflush(stdout);
if (!test_stuck_address(aligned, bufsize / sizeof(ul))) {
printf("ok\n");
} else {
exit_code |= EXIT_FAIL_ADDRESSLINES;
}
for (i=0;;i++) {
if (!tests[i].name) break;
printf(" %-20s: ", tests[i].name);
if (!tests[i].fp(bufa, bufb, count)) {
printf("ok\n");
} else {
exit_code |= EXIT_FAIL_OTHERTEST;
}
fflush(stdout);
}
printf("\n");
fflush(stdout);
}
if (do_mlock) munlock((void *) aligned, bufsize);
printf("Done.\n");
fflush(stdout);
exit(exit_code);
}
So I at the moment only need answer how to start normally this program with another one. It can be the most basic one like hello world and then the execution line of this memtester .
It executes normally when numbers are inserted as arguments, but if I insert `free -om | grep 'Mem:' | awk '{print $4}'`1
for the first argument(for amount of free memory), program exits.
It works normal in the shell, but from a program it doesn't
Have a nice Day
Matt
-
What you need to post is your attempt at passing an integer to it.
-
Can you give me one option to start it?
now is execvp(cmdPath,cmd)
So there is path and arguments in the second.
Arguments and path are located in a txt file.
If I would be a professional programer I wouldn't ask, but I'm a beginner and at the moment I havent got a clue how to solve a problem.
Have a nice Day
Matt
-
HI
I found out that really is an integer problem - function returns character so that's why program returns error.
How can I start program that will return integer values? Please help me I need your help badly.
Have a nice Day
Matt
-
HI
Problem is that the program uses for the first argument:
Code:
`free -om | grep 'Mem:' | awk '{print $4}'`
so the first argument is char - but should be the result of mentioned code that is integer. How can I solve the program that the result would be used as argument not the code for getting the result?
Have a nice Day
Matt
-
> `free -om | grep 'Mem:' | awk '{print $4}'`
You've yet to post any valid C code which is yours.
Like I said, things like `` and | are interpreted by the shell - passing them direct to execl just isn't going to do what you want.
> ./memtester `free -om | grep 'Mem:' | awk '{print $4}'`1
Each of those | characters corresponds to
- a call to pipe() to create a pipe (say between free and grep)
- calls to close() and dup() to redirect stdin/stdout to the ends of the pipe
- a call to fork() to create a separate process
- a call to execl() to run the sub-process (say grep or awk)
Now, you might be able to get away with
Code:
FILE *fp = popen( "free -om | grep 'Mem:' | awk '{print $4}'", "r" );
// use fgets to read a single line of output from that pipeline (this will be a string)
pclose(fp)
// pass that string as part of the vector for an execv call