From 630cb3becfc26fa786ac9567305a928771225445 Mon Sep 17 00:00:00 2001 From: "Safey A.Halim" Date: Tue, 31 Aug 2010 13:54:32 +0000 Subject: [PATCH] Monkey sends e-mails reporting bugs detected using gdbmi C.jj grammar for C --- src/monkey/C.jj | 543 ++++++++++++++++++++++++ src/monkey/Makefile.am | 27 +- src/monkey/bug_null_pointer_exception.c | 14 +- src/monkey/gnunet-monkey.c | 27 +- src/monkey/mail_sender.c | 14 +- src/monkey/test_gnunet_monkey.c | 67 +++ 6 files changed, 652 insertions(+), 40 deletions(-) create mode 100644 src/monkey/C.jj create mode 100644 src/monkey/test_gnunet_monkey.c diff --git a/src/monkey/C.jj b/src/monkey/C.jj new file mode 100644 index 000000000..34e2c4f86 --- /dev/null +++ b/src/monkey/C.jj @@ -0,0 +1,543 @@ +/* + + C grammar defintion for use with JavaCC + Contributed by Doug South (dsouth@squirrel.com.au) 21/3/97 + + This parser assumes that the C source file has been preprocessed : all + #includes have been included and all macros have been expanded. I accomplish + this with "gcc -P -E > ". + + There is a problem with compiler specific types, such as __signed, __const, + __inline__, etc. These types can be added as typedef types before the parser + is run on a file. See main() for an example. I have also found a strange little + compiler specific "type" if you can call it that. It is __attribute__, but it + does not seem to be used as a type. I found that just deleting the __attribute__ + and the following "offensive" code works. + + This grammar also prints out all the types defined while parsing the file. This + is done via a call to printTypes() when the parser is complete. If you do not want + this, just comment out the printTypes() method call in the production rule + TranslationUnit(), which BTW is the root node for parsing a C source file. + + I have not in anyway extensively tested this grammar, in fact it is barely tested, + but I imagine it is better to have a starting point for a C grammar other than from + scratch. It has not been optimized in anyway, my main aim was to get a parser that + works. Lookahead may not be optimum at choice points and may even be insufficient at + times. I choose to err on the side of not optimum if I made a choice at all. + + If you use this grammar, I would appreciate hearing from you. I will try to maintain + this grammar to the best of my ability, but at this point in time, this is only a side + hobby (unless someone wants to pay me for doing JavaCC work!). In that regards, I am + interested in hearing bugs and comments. + + TODO: + + Insert the appropriate code to enable C source trees from this grammar. + +============================================= +3/2/06: Modified by Tom Copeland +- STRING_LITERAL now handles embedded escaped newlines, thanks to J.Chris Findlay for the patch +- Works with JavaCC 4.0 +- Preprocessor directives are now simply SKIP'd, so no need to run C files through GCC first + + */ + +PARSER_BEGIN(CParser) + +import java.util.*; + + public class CParser{ + + // Run the parser + public static void main ( String args [ ] ) { + CParser parser ; + + + if(args.length == 0){ + System.out.println("C Parser Version 0.1Alpha: Reading from standard input . . ."); + parser = new CParser(System.in); + } + else if(args.length == 1){ + System.out.println("C Parser Version 0.1Alpha: Reading from file " + args[0] + " . . ." ); + try { + parser = new CParser(new java.io.FileInputStream(args[0])); + } + catch(java.io.FileNotFoundException e){ + System.out.println("C Parser Version 0.1: File " + args[0] + " not found."); + return ; + } + } + else { + System.out.println("C Parser Version 0.1Alpha: Usage is one of:"); + System.out.println(" java CParser < inputfile"); + System.out.println("OR"); + System.out.println(" java CParser inputfile"); + return ; + } + try { + parser.TranslationUnit(); + System.out.println("C Parser Version 0.1Alpha: Java program parsed successfully."); + } + catch(ParseException e){ + System.out.println("C Parser Version 0.1Alpha: Encountered errors during parse."); + e.printStackTrace(); + } + } + } + +PARSER_END(CParser) + +SKIP : { + " " +| "\t" +| "\n" +| "\r" +| <"//" (~["\n","\r"])* ("\n" | "\r" | "\r\n")> +| <"/*" (~["*"])* "*" ("*" | ~["*","/"] (~["*"])* "*")* "/"> +| "#" : PREPROCESSOR_OUTPUT +} + + SKIP: +{ + "\n" : DEFAULT +} + + MORE: +{ + "\\\n" + | + "\\\r\n" + | + < ~[] > +} + + +TOKEN : { + (["l","L"])? | (["l","L"])? | (["l","L"])?> +| <#DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])*> +| <#HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+> +| <#OCTAL_LITERAL: "0" (["0"-"7"])*> +| )? (["f","F","d","D"])? | "." (["0"-"9"])+ ()? (["f","F","d","D"])? | (["0"-"9"])+ (["f","F","d","D"])? | (["0"-"9"])+ ()? ["f","F","d","D"]> +| <#EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+> +| +| +} + +TOKEN : { + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + +} + +TOKEN : { + ( | )*> +| <#LETTER: ["$","A"-"Z","_","a"-"z"]> +| <#DIGIT: ["0"-"9"]> +} + +void TranslationUnit() : {} +{ + (ExternalDeclaration())+ +} + +void ExternalDeclaration() : {} +{ + ( LOOKAHEAD( FunctionDefinition() ) FunctionDefinition() | Declaration()) +} + +void FunctionDefinition() : {} +{ + [LOOKAHEAD(DeclarationSpecifiers()) DeclarationSpecifiers()] Declarator() [ DeclarationList() ] + CompoundStatement() +} + +void Declaration() : {} +{ + DeclarationSpecifiers() [ InitDeclaratorList() ] ";" +} + +void DeclarationList() : {} +{ + ( LOOKAHEAD(Declaration()) Declaration() )+ +} + +void DeclarationSpecifiers() : {} +{ + StorageClassSpecifier() [ LOOKAHEAD(DeclarationSpecifiers()) + DeclarationSpecifiers() ] | + TypeSpecifier() [ LOOKAHEAD(DeclarationSpecifiers()) + DeclarationSpecifiers() ] | + TypeQualifier() [ LOOKAHEAD(DeclarationSpecifiers()) + DeclarationSpecifiers() ] +} + +void StorageClassSpecifier() : {} +{ + ( | | | | + ) +} + +void TypeSpecifier() : {} +{ + ( | | | | | | | | + | StructOrUnionSpecifier() | EnumSpecifier() | TypedefName() ) +} + +void TypeQualifier() : {} +{ + ( | ) +} + +void StructOrUnionSpecifier() : {} +{ + StructOrUnion() ( LOOKAHEAD(3) [ ] "{" StructDeclarationList() "}" | ) + +} + +void StructOrUnion() : {} +{ + ( | ) +} + +void StructDeclarationList() : {} +{ + (StructDeclaration())+ +} + +void InitDeclaratorList() : {} +{ + InitDeclarator() ("," InitDeclarator())* +} + +void InitDeclarator() : {} +{ + Declarator() [ "=" Initializer() ] +} + +void StructDeclaration() : {} +{ + SpecifierQualifierList() StructDeclaratorList() ";" +} + +void SpecifierQualifierList() : {} +{ + TypeSpecifier() [ LOOKAHEAD(SpecifierQualifierList()) + SpecifierQualifierList() ]| + TypeQualifier() [ LOOKAHEAD(SpecifierQualifierList()) + SpecifierQualifierList() ] +} + +void StructDeclaratorList() : {} +{ + StructDeclarator() ( "," StructDeclarator() )* +} + +void StructDeclarator() : {} +{ + ( LOOKAHEAD(3) Declarator() | [ Declarator() ] ":" ConstantExpression() ) +} + +void EnumSpecifier() : {} +{ + ( LOOKAHEAD(3) [ ] "{" EnumeratorList() "}" | ) +} + +void EnumeratorList() : {} +{ + Enumerator() ("," Enumerator())* +} + +void Enumerator() : {} +{ + [ "=" ConstantExpression() ] +} + +void Declarator() : {} +{ + [ Pointer() ] DirectDeclarator() +} + +void DirectDeclarator() : {} +{ + ( + | "(" Declarator() ")" ) + + ( "[" [ ConstantExpression() ] "]" | + LOOKAHEAD(3) "(" ParameterTypeList() ")" | + "(" [ IdentifierList() ] ")" )* +} + +void Pointer() : {} +{ + "*" [ TypeQualifierList() ] [ Pointer() ] +} + +void TypeQualifierList() : {} +{ + (TypeQualifier())+ +} + +void ParameterTypeList() : {} +{ + ParameterList() ["," "..." ] +} + +void ParameterList() : {} +{ + ParameterDeclaration() (LOOKAHEAD(2) "," ParameterDeclaration())* +} + +void ParameterDeclaration() : {} +{ + DeclarationSpecifiers() ( LOOKAHEAD(Declarator()) Declarator() | [ AbstractDeclarator() ] ) +} + +void IdentifierList() : {} +{ + ("," )* +} + +void Initializer() : {} +{ + ( AssignmentExpression() | + "{" InitializerList() [","] "}" ) +} + +void InitializerList() : {} +{ + Initializer() (LOOKAHEAD(2) "," Initializer())* +} + +void TypeName() : {} +{ + SpecifierQualifierList() [ AbstractDeclarator() ] + +} + +void AbstractDeclarator() : {} +{ + ( LOOKAHEAD(3) Pointer() | + [Pointer()] DirectAbstractDeclarator() ) +} + +void DirectAbstractDeclarator() : {} +{ + ( LOOKAHEAD(2) "(" AbstractDeclarator() ")" | + "[" [ConstantExpression()] "]" | + "(" [ParameterTypeList()] ")" ) + + ( "[" [ ConstantExpression() ] "]" | "(" [ ParameterTypeList() ] ")" )* +} + +void TypedefName() : {} +{ + +} + +void Statement() : {} +{ + ( LOOKAHEAD(2) LabeledStatement() | + ExpressionStatement() | + CompoundStatement() | + SelectionStatement() | + IterationStatement() | + JumpStatement() ) +} + +void LabeledStatement() : {} +{ + ( ":" Statement() | + ConstantExpression() ":" Statement() | + ":" Statement() ) +} + +void ExpressionStatement() : {} +{ + [ Expression() ] ";" +} + +void CompoundStatement() : {} +{ + "{" [ LOOKAHEAD(DeclarationList()) DeclarationList() ] + [ StatementList() ] + "}" +} + +void StatementList() : {} +{ + (Statement())+ +} + +void SelectionStatement() : {} +{ + ( "(" Expression() ")" Statement() [ LOOKAHEAD(2) Statement() ] | + "(" Expression() ")" Statement() ) +} + +void IterationStatement() : {} +{ + ( "(" Expression() ")" Statement() | + Statement() "(" Expression() ")" ";" | + "(" [ Expression() ] ";" [ Expression() ] ";" [ Expression() ] ")" Statement() ) +} + +void JumpStatement() : {} +{ + ( ";" | + ";" | + ";" | + [ Expression() ] ";" ) +} + +void Expression() : {} +{ + AssignmentExpression() ( "," AssignmentExpression() )* +} + +void AssignmentExpression() : {} +{ + LOOKAHEAD(UnaryExpression() AssignmentOperator()) UnaryExpression() AssignmentOperator() AssignmentExpression() | + LOOKAHEAD(3) ConditionalExpression() +} + +void AssignmentOperator() : {} +{ + ( "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | "&=" | "^=" | "|=" ) +} + +void ConditionalExpression() : {} +{ + LogicalORExpression() [ "?" Expression() ":" ConditionalExpression() ] +} + +void ConstantExpression() : {} +{ + ConditionalExpression() +} + +void LogicalORExpression() : {} +{ + LogicalANDExpression() [ "||" LogicalORExpression() ] +} + +void LogicalANDExpression() : {} +{ + InclusiveORExpression() [ "&&" LogicalANDExpression() ] +} + +void InclusiveORExpression() : {} +{ + ExclusiveORExpression() [ "|" InclusiveORExpression() ] +} + +void ExclusiveORExpression() : {} +{ + ANDExpression() [ "^" ExclusiveORExpression() ] +} + +void ANDExpression() : {} +{ + EqualityExpression() [ "&" ANDExpression() ] +} + +void EqualityExpression() : {} +{ + RelationalExpression() [ ( "==" | "!=" ) EqualityExpression() ] +} + +void RelationalExpression() : {} +{ + ShiftExpression() [ ( "<" | ">" | "<=" | ">=" ) RelationalExpression() ] +} + +void ShiftExpression() : {} +{ + AdditiveExpression() [ ( "<<" | ">>" ) ShiftExpression() ] +} + +void AdditiveExpression() : {} +{ + MultiplicativeExpression() [ ( "+" | "-" ) AdditiveExpression() ] +} + +void MultiplicativeExpression() : {} +{ + CastExpression() [ ( "*" | "/" | "%" ) MultiplicativeExpression() ] +} + +void CastExpression() : {} +{ + ( LOOKAHEAD("(" TypeName() ")" CastExpression() ) "(" TypeName() ")" CastExpression() | + UnaryExpression() ) +} + +void UnaryExpression() : {} +{ + ( LOOKAHEAD(3) PostfixExpression() | + "++" UnaryExpression() | + "--" UnaryExpression() | + UnaryOperator() CastExpression() | + ( LOOKAHEAD(UnaryExpression() ) UnaryExpression() | "(" TypeName() ")" ) ) +} + +void UnaryOperator() : {} +{ + ( "&" | "*" | "+" | "-" | "~" | "!" ) +} + +void PostfixExpression() : {} +{ + PrimaryExpression() ( "[" Expression() "]" | + "(" [ LOOKAHEAD(ArgumentExpressionList() ) ArgumentExpressionList() ] ")" | + "." | + "->" | + "++" | + "--" )* +} + +void PrimaryExpression() : {} +{ + ( | + Constant() | + "(" Expression() ")" ) +} + +void ArgumentExpressionList() : {} +{ + AssignmentExpression() ( "," AssignmentExpression() )* +} + +void Constant() : {} +{ + | | | +} + diff --git a/src/monkey/Makefile.am b/src/monkey/Makefile.am index 6d4250b89..2f8ca295c 100644 --- a/src/monkey/Makefile.am +++ b/src/monkey/Makefile.am @@ -16,8 +16,7 @@ if HAVE_OPENSSL bin_PROGRAMS = \ gnunet-monkey \ - gnunet-service-monkey \ - mail_sender + gnunet-service-monkey noinst_PROGRAMS = \ bug_null_pointer_exception @@ -39,10 +38,12 @@ gnunet_monkey_SOURCES = \ gdbmi_target_man.c \ gdbmi_thread.c \ gdbmi_var_obj.c \ - gnunet-monkey.c + gnunet-monkey.c \ + mail_sender.c gnunet_monkey_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ + -lesmtp \ $(GN_LIBINTL) @@ -53,23 +54,27 @@ gnunet_service_monkey_LDADD = \ $(GN_LIBINTL) -mail_sender_SOURCES = \ - mail_sender.c -mail_sender_LDADD = \ - $(top_builddir)/src/util/libgnunetutil.la \ - -lesmtp \ - $(GN_LIBINTL) - bug_null_pointer_exception_SOURCES = \ bug_null_pointer_exception.c bug_null_pointer_exception_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(GN_LIBINTL) + +check_PROGRAMS = \ + bug_null_pointer_exception \ + test_gnunet_monkey if !DISABLE_TEST_RUN -#TESTS = $(check_PROGRAMS) $(check_SCRIPTS) +# TESTS = $(check_SCRIPTS) endif +test_gnunet_monkey_SOURCES = \ + test_gnunet_monkey.c +test_gnunet_monkey_LDADD = \ + $(top_builddir)/src/arm/libgnunetarm.la \ + $(top_builddir)/src/util/libgnunetutil.la + + check_SCRIPTS = \ test_gnunet_monkey.sh # test_monkey_npe.sh diff --git a/src/monkey/bug_null_pointer_exception.c b/src/monkey/bug_null_pointer_exception.c index 977fb088c..072904b6d 100644 --- a/src/monkey/bug_null_pointer_exception.c +++ b/src/monkey/bug_null_pointer_exception.c @@ -3,25 +3,15 @@ void crashFunction() { - //char *stringCannotBeChanged = "String cannot be changed!"; char *nullString = NULL; - - printf("Now the program will crash! Take a cover! \n"); - //*stringCannotBeChanged = 'h'; - printf("Nonsense!\n"); + printf("Now the program will crash!\n"); if (strcmp(nullString, "A string to compare with") == 0) { - printf("How come?! It had to be crashed!\n"); + printf("How come?! It had to crash!\n"); } } int main(int argc, char *argv[]) { - int i; - printf("arguments: %d\n", argc); - for (i=0; i //usleep #include #include "gdbmi.h" +#include "platform.h" +#include "gnunet_common.h" + +extern void sendMail(const char *messageContents); void cb_console(const char *str, void *data) { @@ -48,6 +52,16 @@ void cb_async(mi_output *o, void *data) async_c++; } + +void send_bug_mail(mi_stop* sr, mi_frames* f) +{ + char *message; + asprintf(&message, "Bug detected in file:%s\nfunction:%s\nline:%d\nreason:%s\nreceived signal:%s\n%s\n", + f->file, f->func, f->line, mi_reason_enum_to_str(sr->reason), sr->signal_name, sr->signal_meaning); + sendMail(message); +} + + int wait_for_stop(mi_h *h) { int res=1; @@ -60,13 +74,10 @@ int wait_for_stop(mi_h *h) sr=mi_res_stop(h); if (sr) { - printf("Stopped, reason: %s\n",mi_reason_enum_to_str(sr->reason)); - printf("Received signal name: %s\n", sr->signal_name); - printf("Received signal meaning: %s\n", sr->signal_meaning); - //printf("In file: %s\n", sr->frame->file); - //printf("Line Number: %d\n", sr->frame->line); f = gmi_stack_info_frame(h); + send_bug_mail(sr, f); mi_free_stop(sr); + res = 0; } else { @@ -80,6 +91,10 @@ int wait_for_stop(mi_h *h) int main(int argc, char *argv[]) { mi_aux_term *xterm_tty=NULL; + const char* binaryName; + + binaryName = argv[1]; + GNUNET_assert(NULL != binaryName); /* This is like a file-handle for fopen. Here we have all the state of gdb "connection". */ @@ -103,7 +118,7 @@ int main(int argc, char *argv[]) mi_set_from_gdb_cb(h,cb_from,NULL); /* Set the name of the child and the command line aguments. */ - if (!gmi_set_exec(h,"bug_null_pointer_exception", NULL)) + if (!gmi_set_exec(h, binaryName, NULL)) { printf("Error setting exec y args\n"); mi_disconnect(h); diff --git a/src/monkey/mail_sender.c b/src/monkey/mail_sender.c index 385198d06..b9420a306 100644 --- a/src/monkey/mail_sender.c +++ b/src/monkey/mail_sender.c @@ -145,18 +145,17 @@ print_recipient_status (smtp_recipient_t recipient, } -void sendMail() +void sendMail(const char *messageContents) { smtp_session_t session; smtp_message_t message; smtp_recipient_t recipient; - // auth_context_t authctx; const smtp_status_t *status; struct sigaction sa; char *host = "localhost:25"; char *from = "gnunet-monkey"; char *subject = "e-mail from Libesmtp!"; - const char *recipient_address = "halims@in.tum.de"; + const char *recipient_address = "safey.allah@gmail.com"; char tempFileName[1000]; int tempFd; FILE *fp; @@ -193,7 +192,7 @@ void sendMail() sprintf(tempFileName, "/tmp/messageXXXXXX"); tempFd = mkstemp(tempFileName); fp = fdopen(tempFd, "w"); - fprintf(fp, "Hello! This is a test message!\r\n"); + fprintf(fp, messageContents); fclose(fp); fp = fopen(tempFileName, "r"); smtp_set_message_fp(message, fp); @@ -222,14 +221,7 @@ void sendMail() /* Free resources consumed by the program. */ smtp_destroy_session(session); - // auth_destroy_context(authctx); fclose(fp); auth_client_exit(); - exit(0); } -int main() -{ - sendMail(); - return 0; -} diff --git a/src/monkey/test_gnunet_monkey.c b/src/monkey/test_gnunet_monkey.c new file mode 100644 index 000000000..9fa56f508 --- /dev/null +++ b/src/monkey/test_gnunet_monkey.c @@ -0,0 +1,67 @@ +/* + This file is part of GNUnet. + (C) 2009 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file monkey/test_gnunet_monkey.c + * @brief Testcase for Monkey + * @author Safey Abdel Halim + */ + +/** + * Test case for Monkey Automatic Debugger. + * It launches Monkey to run binaries having + * known bugs (e.g. Null Pointer Exception) + * Monkey should be able to detect the problem and send an e-mail + * containing the problem description. + */ + + +#include "platform.h" +#include "gnunet_common.h" +#include "gnunet_util_lib.h" +#include "gnunet_program_lib.h" + + +static int +check () +{ + GNUNET_OS_start_process (NULL, NULL, "gnunet-monkey", + "gnunet-monkey", + "./bug_null_pointer_exception", NULL); + return 0; +} + + +int +main (int argc, char *argv[]) +{ + int ret; + + GNUNET_log_setup ("test-gnunet-monkey", +#if VERBOSE + "DEBUG", +#else + "WARNING", +#endif + NULL); + ret = check (); + return ret; +} +/* end of test_gnunet_monkey.c */ \ No newline at end of file -- 2.25.1