Thread: Function with multiple arguments problem

  1. #1
    Registered User
    Join Date
    Jan 2015
    Posts
    2

    Function with multiple arguments problem

    Hello,
    It is my first post here

    I am actually developping an nginx module in C.
    I am not to bad in C, but i got a big problem to pass argument to a vadiadic function.
    This function look like the well good old printf, but you put a buffer as first argument, the last address to stop to put data as second argument (in my case it is the last adress of disponible memory), a string that look like one in printf, an the other argument after.

    Here is the problem, the 4th last argument does not have the good value. In fact, It seem to be random value from memory. I Use gcc (Debian 4.9.1-19) 4.9.1.

    Code:
    /* ngx_html_log.h */
    
    #ifndef NGX_HTML_LOG_H
    #define NGX_HTML_LOG_H
    #include <ngx_vasm.h>
    
    void ngx_html_dump__ngx_buf_t(ngx_buf_t * b, const char * token_name, const char * zone_name);
    #define ngx_html_reset_buf(buffer) buffer.pos = buffer.start
            
    #define ngx_html_dump(var_type, var, token_name, zone_name)\
            ngx_vasm_set_rip_register();\
            ngx_html_dump__##var_type(var, token_name, zone_name)
    #endif
    Code:
    /* ngx_html_log.c */
    
    #include <ngx_config.h>
    #include <ngx_core.h>
    #include <ngx_http.h>
    #include <ngx_vasm.h>
    
    #define NGX_HTML_DEBUG_DATA_SIZE 0x10000
    
    static u_char ngx_html_debug_data[NGX_HTML_DEBUG_DATA_SIZE];
    
    ngx_buf_t ngx_html_debug_buf = {
            .start = ngx_html_debug_data,
            .pos = ngx_html_debug_data,
            .last = ngx_html_debug_data + NGX_HTML_DEBUG_DATA_SIZE - 1,
            .end = ngx_html_debug_data + NGX_HTML_DEBUG_DATA_SIZE - 1
    };
    
    void
    ngx_html_dump__ngx_buf_t(ngx_buf_t * b, const char * token_name, const char * zone_name){
            ngx_html_debug_buf.pos = ngx_slprintf(ngx_html_debug_buf.pos, ngx_html_debug_buf.last,
                    "<table border=\"2\">"
                            "<caption>%s:%s (%%rip:0x%p)</caption>"
                            "<tr><td>%s->pos</td><td>0x%p</td></tr>"
                            "<tr><td>%s->last</td><td>0x%p</td></tr>"
                            "<tr><td>%s->file_pos</td><td>0x%p</td></tr>"
                            "<tr><td>%s->file_last</td><td>0x%p</td></tr>"
                            "<tr><td>%s->start</td><td>0x%p</td></tr>"
                            "<tr><td>%s->end</td><td>0x%p</td></tr>"
                            "<tr><td>%s->tag</td><td>0x%p</td></tr>"
                            "<tr><td>%s->file</td><td>0x%p</td></tr>"
                            "<tr><td>%s->shadow</td><td>0x%p</td></tr>"
                            "<tr><td>%s->temporary</td><td>0x%p</td></tr>"
                            "<tr><td>%s->memory</td><td>0x%p</td></tr>"
                            "<tr><td>%s->mmap</td><td>0x%p</td></tr>"
                            "<tr><td>%s->recycled</td><td>0x%p</td></tr>"
                            "<tr><td>%s->in_file</td><td>0x%p</td></tr>"
                            "<tr><td>%s->flush</td><td>0x%p</td></tr>"
                            "<tr><td>%s->sync</td><td>0x%p</td></tr>"
                            "<tr><td>%s->last_buf</td><td>0x%p</td></tr>"
                            "<tr><td>%s->last_in_chain</td><td>0x%p</td></tr>"
                            "<tr><td>%s->last_shadow</td><td>0x%p</td></tr>"
                            "<tr><td>%s->temp_file</td><td>0x%p</td></tr>"
                            "<tr><td>%s->num</td><td>0x%p</td></tr>"
                    "</table>"
                    ,zone_name
                    ,token_name
                    ,ngx_vasm__rip
                    ,token_name
                    ,b->file_pos
                    ,token_name
                    ,b->file_last
                    ,token_name
                    ,b->start
                    ,token_name
                    ,b->end
                    ,token_name
                    ,b->tag
                    ,token_name
                    ,b->file
                    ,token_name
                    ,b->shadow
                    ,token_name
                    ,b->temporary
                    ,token_name
                    ,b->memory
                    ,token_name
                    ,b->mmap
                    ,token_name
                    ,b->recycled
                    ,token_name
                    ,b->in_file
                    ,token_name
                    ,b->flush
                    ,token_name
                    ,b->sync
                    ,token_name
                    ,b->last_buf
                    ,token_name
                    ,b->last_in_chain
                    ,token_name
                    ,128//b->last_shadow
                    ,"test1"//token_name
                    ,0//b->temp_file
                    ,"test2"//token_name
                    ,0//b->num
            );
    }
    Code:
    /* ngx_vash.h */
    #ifndef NGX_VASM_H
    #define NGX_VASM_H
    
    /*TODO invert test and put in a config file*/
    #ifndef NGX_USE_MONO_THREADED_VASM
    #define NGX_USE_MONO_THREADED_VASM 1
    #endif
    
    #if NGX_USE_MONO_THREADED_VASM
    extern uint64_t ngx_vasm__rip;
    #define ngx_vasm_set_rip_register()\
            asm(\
                    "leaq (%%rip), %0;\n\t"\
                    : "=r" (ngx_vasm__rip)\
            );
    #else
    #define ngx_vasm_create_rip_register(ngx_vasm__rip) uint64_t ngx_vasm__rip;
    #define ngx_vasm_set_rip_register(ngx_vasm__rip)\
            asm(\
                    "leaq (%%rip), %0;\n\t"\
                    : "=r" (ngx_vasm__rip)\
            );
    #endif
    #endif
    Code:
    /* ngx_vasm.c */
    #include <stdint.h>
    uint64_t ngx_vasm__rip;

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    You have to read more carefully . I count 45 format specifiers in the format string, but only 41 supplemental args passed to the function. You seem to be missing two struct members and the token_name that goes with each -- missing 4 params, that's why the garbage starts at the fourth-to-last one.

  3. #3
    Registered User
    Join Date
    Jan 2015
    Posts
    2
    Thank you a lot anduril, there was some members that i did not pass. i thought that i passed them all. I am sorry to have not think that there was the problem..... i feel a bit stupid, but it is ok, next time i will count my argument first :P

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    https://gcc.gnu.org/onlinedocs/gcc-4...ion-Attributes
    Check out the format attribute.
    You should be able to get gcc to check all these things for you, if the function follows the basic printf style rules.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem changing function arguments
    By MartinR in forum C Programming
    Replies: 8
    Last Post: 02-08-2014, 06:17 AM
  2. Pthread question, multiple arguments
    By Alix in forum C Programming
    Replies: 2
    Last Post: 02-12-2012, 10:58 AM
  3. help with pthread and multiple arguments
    By user_name_void in forum C Programming
    Replies: 4
    Last Post: 02-17-2010, 03:23 PM
  4. Sending multiple arguments to function..
    By Zzaacchh in forum C++ Programming
    Replies: 3
    Last Post: 09-06-2008, 03:20 PM
  5. multiple command line arguments
    By christee in forum C Programming
    Replies: 4
    Last Post: 04-08-2003, 08:35 AM

Tags for this Thread