Add valgrind tests and fix memleaks

This commit is contained in:
josch
2014-09-21 00:03:20 +02:00
parent 122db2ed82
commit 042a1cdf09
16 changed files with 177 additions and 18 deletions

View File

@@ -18,5 +18,6 @@ target_link_libraries(mfshell curl ssl crypto jansson mfapi mfutils)
enable_testing()
add_test(iwyu ../tests/iwyu.py)
add_test(indent ../tests/indent.sh)
add_test(iwyu ${CMAKE_SOURCE_DIR}/tests/iwyu.py ${CMAKE_BINARY_DIR})
add_test(indent ${CMAKE_SOURCE_DIR}/tests/indent.sh ${CMAKE_SOURCE_DIR})
add_test(valgrind ${CMAKE_SOURCE_DIR}/tests/valgrind.sh ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR})

View File

@@ -19,6 +19,7 @@
#include <jansson.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../../utils/http.h"
@@ -58,6 +59,8 @@ int mfconn_api_file_get_info(mfconn * conn, mffile * file, char *quickkey)
retval = http_get_buf(http, api_call, _decode_file_get_info, file);
http_destroy(http);
free(api_call);
return retval;
}

View File

@@ -19,6 +19,7 @@
#include <jansson.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../../utils/http.h"
@@ -58,6 +59,8 @@ int mfconn_api_file_get_links(mfconn * conn, mffile * file, char *quickkey)
retval = http_get_buf(http, api_call, _decode_file_get_links, file);
http_destroy(http);
free(api_call);
return retval;
}

View File

@@ -18,6 +18,7 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../../utils/http.h"
@@ -63,5 +64,7 @@ int mfconn_api_folder_create(mfconn * conn, char *parent, char *name)
retval = http_get_buf(http, api_call, NULL, NULL);
http_destroy(http);
free(api_call);
return retval;
}

View File

@@ -18,6 +18,7 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../../utils/http.h"
@@ -47,5 +48,7 @@ int mfconn_api_folder_delete(mfconn * conn, const char *folderkey)
retval = http_get_buf(http, api_call, NULL, NULL);
http_destroy(http);
free(api_call);
return retval;
}

View File

@@ -75,6 +75,8 @@ mfconn_api_folder_get_content(mfconn * conn, int mode, mffolder * folder_curr)
_decode_folder_get_content_files, NULL);
http_destroy(http);
free(api_call);
return retval;
}

View File

@@ -19,6 +19,7 @@
#include <jansson.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../../utils/http.h"
@@ -58,6 +59,8 @@ mfconn_api_folder_get_info(mfconn * conn, mffolder * folder, char *folderkey)
retval = http_get_buf(http, api_call, _decode_folder_get_info, folder);
http_destroy(http);
free(api_call);
return retval;
}

View File

@@ -19,6 +19,7 @@
#include <jansson.h>
#include <stdio.h>
#include <stdlib.h>
#include "../../utils/http.h"
#include "../../utils/json.h"
@@ -45,6 +46,8 @@ int mfconn_api_user_get_info(mfconn * conn)
retval = http_get_buf(http, api_call, _decode_user_get_info, NULL);
http_destroy(http);
free(api_call);
return retval;
}

View File

@@ -69,6 +69,7 @@ mfconn_api_user_get_session_token(mfconn * conn, char *server,
"&token_version=2"
"&response_format=json",
username, password, user_signature);
free(user_signature);
http = http_create();
retval =

View File

@@ -27,9 +27,9 @@
#include "mfshell.h"
static void mfshell_run(mfshell * mfshell);
static void mfshell_run(mfshell * shell);
static void mfshell_parse_commands(mfshell * mfshell, char *command);
static void mfshell_parse_commands(mfshell * shell, char *command);
void print_help(char *cmd)
{
@@ -119,7 +119,7 @@ parse_argv(int argc, char **argv, char **username,
int main(int argc, char **argv)
{
mfshell *mfshell;
mfshell *shell;
char *server = "www.mediafire.com";
char *username = NULL;
char *password = NULL;
@@ -129,22 +129,32 @@ int main(int argc, char **argv)
parse_argv(argc, argv, &username, &password, &server, &command);
mfshell = mfshell_create(35860,
"2c6dq0gb2sr8rgsue5a347lzpjnaay46yjazjcjg",
shell = mfshell_create(35860, "2c6dq0gb2sr8rgsue5a347lzpjnaay46yjazjcjg",
server);
if (command == NULL) {
// begin shell mode
mfshell_run(mfshell);
mfshell_run(shell);
} else {
// interpret command
mfshell_parse_commands(mfshell, command);
mfshell_parse_commands(shell, command);
}
mfshell_destroy(shell);
if (server != NULL && strcmp("www.mediafire.com", server) != 0)
free(server);
if (username != NULL)
free(username);
if (password != NULL)
free(password);
if (command != NULL)
free(command);
return 0;
}
static void mfshell_parse_commands(mfshell * mfshell, char *command)
static void mfshell_parse_commands(mfshell * shell, char *command)
{
char *next;
int ret;
@@ -177,12 +187,12 @@ static void mfshell_parse_commands(mfshell * mfshell, char *command)
fprintf(stderr, "Need more than zero arguments\n");
exit(1);
}
mfshell_exec(mfshell, p.we_wordc, p.we_wordv);
mfshell_exec(shell, p.we_wordc, p.we_wordv);
wordfree(&p);
}
}
static void mfshell_run(mfshell * mfshell)
static void mfshell_run(mfshell * shell)
{
char *cmd = NULL;
size_t len;
@@ -212,7 +222,7 @@ static void mfshell_run(mfshell * mfshell)
continue;
}
retval = mfshell_exec_shell_command(mfshell, cmd);
retval = mfshell_exec_shell_command(shell, cmd);
free(cmd);
cmd = NULL;
}

View File

@@ -142,3 +142,13 @@ int mfshell_exec_shell_command(mfshell * shell, char *command)
return 0;
}
void mfshell_destroy(mfshell * shell)
{
free(shell->app_key);
free(shell->server);
free(shell->local_working_dir);
folder_free(shell->folder_curr);
mfconn_destroy(shell->conn);
free(shell);
}

View File

@@ -61,4 +61,6 @@ int mfshell_exec(mfshell * mfshell, int argc, char **argv);
int mfshell_exec_shell_command(mfshell * mfshell, char *command);
void mfshell_destroy(mfshell * shell);
#endif

View File

@@ -1,12 +1,27 @@
#!/bin/sh
ret=0
find .. -name "*.c" -o -name "*.h" | while read f; do
case $f in
../*/CMakeFiles/*)
case $# in
0)
source_dir="."
;;
1)
source_dir=$1
;;
*)
INDENT_PROFILE=../.indent.pro indent -st $f | diff -u $f -
echo "usage: $0 [source_dir]"
exit 1
;;
esac
ret=0
find "$source_dir" -name "*.c" -o -name "*.h" | while read f; do
case $f in
${source_dir}/*/CMakeFiles/*)
;;
${source_dir}/CMakeFiles/*)
;;
*)
INDENT_PROFILE="${source_dir}/.indent.pro" indent -st "$f" | diff -u "$f" -
ret=$((ret+$?))
;;
esac

View File

@@ -5,8 +5,20 @@ from __future__ import print_function
import json
import subprocess
import shlex
import sys
import os
with open("compile_commands.json", "r") as f:
if len(sys.argv) == 1:
build_dir = "."
elif len(sys.argv) == 2:
build_dir = sys.argv[1]
else:
print("usage: %s [build_dir]"%sys.argv[0])
exit(1)
compile_commands = os.path.join(build_dir, "compile_commands.json")
with open(compile_commands, "r") as f:
tunits = json.load(f)
result = 0

20
tests/valgrind.sh Executable file
View File

@@ -0,0 +1,20 @@
#!/bin/sh
case $# in
0)
source_dir="."
binary_dir="."
;;
2)
source_dir=$1
binary_dir=$2
;;
*)
echo "usage: $0 [source_dir] [binary_dir]"
exit 1
;;
esac
cmd="valgrind --suppressions="${source_dir}/valgrind.supp" --fullpath-after="$source_dir" --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes --track-origins=yes"
$cmd "${binary_dir}/mfshell" -c "help; whoami"

68
valgrind.supp Normal file
View File

@@ -0,0 +1,68 @@
{
glibc #1
Memcheck:Value8
...
fun:dl_main
fun:_dl_sysdep_start
fun:_dl_start
obj:*/ld-2.*.so
...
}
{
glibc #2
Memcheck:Cond
...
fun:dl_main
fun:_dl_sysdep_start
fun:_dl_start
obj:*/ld-2.*.so
...
}
{
glibc #3
Memcheck:Param
sendmsg(mmsg[0].msg_hdr)
fun:sendmmsg
fun:__libc_res_nsend
fun:__libc_res_nquery
fun:__libc_res_nquerydomain
fun:__libc_res_nsearch
fun:_nss_dns_gethostbyname4_r
fun:gaih_inet
fun:getaddrinfo
...
fun:start_thread
fun:clone
}
{
Since we can never safely uninitialize SSL, allow this
Memcheck:Leak
...
fun:SSL_library_init
fun:main
}
{
gnutls #1
Memcheck:Leak
...
fun:gnutls_global_init
obj:*
fun:call_init.part.0
fun:_dl_init
...
}
{
gnutls #2
Memcheck:Cond
fun:gnutls_session_get_data
...
fun:curl_multi_perform
fun:curl_easy_perform
fun:http_post_buf
fun:mfconn_api_user_get_session_token
fun:mfconn_create
fun:mfshell_cmd_auth
fun:mfshell_exec
fun:mfshell_parse_commands
fun:main
}