/* @(#) $Id: jsontest.c 1634 2020-09-10 23:34:09Z leres $ (LBL) */ #ifdef __FreeBSD__ #include #include #include #endif #include #include #include #include #include #include #include #ifdef __FreeBSD__ #define MEMDEBUG() memdebug(__FILE__, __LINE__) #else #define MEMDEBUG() do {} while(0) #endif extern void memdebug(const char *, int); /* Forwards */ int main(int, char **); void usage(void) __attribute__((noreturn)); #ifdef __FreeBSD__ static void _check(const char *, int, segsz_t, vm_size_t); static void _fetch(segsz_t *, vm_size_t *); #endif /* Globals */ int debug; int repeat = 10000000; int dosleep; const char *prog; /* Locals */ static const char test[] = "{\"info\": \"Updated GigaFilter, 1 entries deleted\n\"}"; #ifdef __FreeBSD__ static segsz_t last_rss; static vm_size_t last_vsz; #endif int main(int argc, char **argv) { int i, op, ret; size_t cc; long uv; FILE *f; char *cp, *ep, *fn; const char *jstr; json_object *jparp; char buf[8192]; if (argv[0] == NULL) prog = "jsontest"; else if ((cp = strrchr(argv[0], '/')) != NULL) prog = cp + 1; else prog = argv[0]; opterr = 0; while ((op = getopt(argc, argv, "dr:")) != EOF) switch (op) { case 'd': ++debug; break; case 'r': uv = strtol(optarg, &ep, 10); if (uv < 1 || *ep != '\0') { fprintf(stderr, "%s: bad -r repeat value \"%s\"\n", prog, optarg); exit(1); } repeat = uv; break; case 's': dosleep = 1; break; default: usage(); /* NOTREACHED */ } argc -= optind; argv += optind; jstr = test; if (argc > 0) { fn = *argv; --argc; ++argv; f = fopen(fn, "r"); if (f == NULL) { fprintf(stderr, "%s: %s: %s\n", prog, fn, strerror(errno)); exit (1); } cc = fread(buf, sizeof(buf), 1, f); fclose(f); if (cc > sizeof(buf) - 3) { fprintf(stderr, "%s: %s: too big\n", prog, fn); exit (1); } jstr = buf; } if (argc != 0) usage(); fprintf(stderr, "######## jsontest %s pid %d\n", JSON_C_VERSION, getpid()); if (debug) fprintf(stderr, "jstr: %s\n", jstr); ret = 0; for (i = 0; i < repeat; ++i) { jparp = json_tokener_parse(jstr); MEMDEBUG(); json_object_put(jparp); } if (dosleep) for (;;) sleep(60); exit(ret); } void usage(void) { fprintf(stderr, "Usage: %s [-dms] [-r N] [JFILE]\n", prog); exit(EX_USAGE); } #ifdef __FreeBSD__ static void _check(const char *sn, int line, segsz_t rss, vm_size_t vsz) { if (last_rss == 0 || last_vsz == 0) { fprintf(stderr, "%s:%d initial rss=%zu, vsz=%zu\n", sn, line, rss, vsz); fflush(stderr); last_rss = rss; last_vsz = vsz; } if (last_rss != rss || last_vsz != vsz) { fprintf(stderr, "%s:%d", sn, line); if (last_rss != rss) { fprintf(stderr, " rss %zu -> %zu", last_rss, rss); last_rss = rss; } if (last_vsz != vsz) { fprintf(stderr, " vsz %zu -> %zu", last_vsz, vsz); last_vsz = vsz; } fprintf(stderr, "\n"); fflush(stderr); } } #define XNAMELEN 4 static void _fetch(segsz_t *rssp, vm_size_t *vszp) { struct kinfo_proc *kipp; int mib[XNAMELEN]; size_t len; pid_t pid; pid = getpid(); len = 0; mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_PID; mib[3] = pid; if (sysctl(mib, XNAMELEN, NULL, &len, NULL, 0) < 0) { fprintf(stderr, "sysctl 1: %s\n", strerror(errno)); exit(1); } kipp = malloc(len); if (kipp == NULL) { fprintf(stderr, "malloc: %s\n", strerror(errno)); exit(1); } if (sysctl(mib, XNAMELEN, kipp, &len, NULL, 0) < 0) { fprintf(stderr, "sysctl 2: %s\n", strerror(errno)); exit(1); } if (len != sizeof(*kipp)) { fprintf(stderr, "bad size 1\n"); exit(1); } if (kipp->ki_structsize != sizeof(*kipp)) { fprintf(stderr, "bad size 1\n"); exit(1); } if (kipp->ki_pid != pid) { fprintf(stderr, "bad pid 1\n"); exit(1); } *rssp = kipp->ki_rssize; *vszp = kipp->ki_size; free(kipp); } void memdebug(const char *fn, int line) { const char *sn; segsz_t rss; vm_size_t vsz; sn = strrchr(fn, '/'); if (sn != NULL) ++sn; else sn = fn; _fetch(&rss, &vsz); _check(sn, line, rss, vsz); } #endif