[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: Segfault from call through a function pointer in assert_int_equal()


Hi Lukas,
I have tried to reproduce this with a small sample using both C and C++. Test files are attached so you can see what I did. In both examples the function pointer behaved as expected. In the C++ variant I even tried adding an argument to the function and it made no difference.

Perhaps it is a result of mixing C and C++. Perhaps I have gotten something wrong with mixing C and C++ that caused the function to be called through the pointer with the wrong calling convention. The C++ example just has all code included in an 'extern "C"' block but I also tried moving two_test_success(), ret_one() and fp_one() out of the 'extern "C"' block to force C++ calling conventions and could find no combination that resulted in a segment fault.

Perhaps I have managed to contrive some combination of C/C++ in my original program (over several files) that has resulted in the wrong calling convention and led to this problem.

I returned to the original test program and tried explicit dereferencing and that works without problems. Then I returned the code to the example that faulted and that now runs without difficulty. This leaves me a little confused. I have continued work on additional tests in the mean time but I have not changed the tests that involved the segfault. I commented out the additional tests thinking that perhaps the problem occurred when the program finished after executing the pointer dereference test and that also made no difference.

At present I am unable to reproduce the problem with contrived code or the original code. I'm inclined to move on but if there is anything you would like me to try I will do so.

Thanks,
hank

-----Original Message-----
From: Barta, Hank
Sent: Friday, October 14, 2016 2:41 PM
To: cmocka@xxxxxxxxxxxxxx
Subject: RE: Segfault from call through a function pointer in assert_int_equal()

Hi Lukas,
I'm 5 minutes away from heading out for a week of vacation (and trying to get somethings worked out before I leave.)

I can take a look at that when I return. It should be pretty easy.

Thanks,
hank

-----Original Message-----
From: Lukas Slebodnik [mailto:lslebodn@xxxxxxxxxx]
Sent: Friday, October 14, 2016 1:49 PM
To: Barta, Hank <hank.barta@xxxxxxxxx>
Cc: cmocka@xxxxxxxxxxxxxx
Subject: Re: Segfault from call through a function pointer in assert_int_equal()

On (14/10/16 15:56), Barta, Hank wrote:
>Hi all,
>I find I get a segfault in the following code:
>    assert_int_equal(0, run_fft(dbl_data, cplx_result, sample_count));
Does it help if you call it with explicit dereferencing?
"(*run_fft)(dbl_data, cplx_result, sample_count)"

Did you try write a minimal reproducer with ANSI C?

LS
________________________________
NOTICE OF CONFIDENTIALITY:
This message may contain information that is considered confidential and which may be prohibited from disclosure under applicable law or by contractual agreement. The information is intended solely for the use of the individual or entity named above. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution or use of the information contained in or attached to this message is strictly prohibited. If you have received this email transmission in error, please notify the sender by replying to this email and then delete it from your system.
// Starting with example at https://api.cmocka.org/index.html (A Cmocka test)
// purpose is to test various usage of function pointers in Cmocka API

// gcc -o demo_segfault -lcmocka demo_segfault.c -lcmocka

#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>

/* A test case that does nothing and succeeds. */
static void null_test_success(void **state) {
    (void) state; /* unused */
}

void (*fp)(void** state) = null_test_success;

/* Perform two tests that should succeed */
static int ret_one(void) {
    return 1;
}
int (*fp_one)(void) = ret_one;

static void two_test_success(void **state) {
    (void) state; /* unused */
    assert_int_equal(1, ret_one());
    assert_int_equal(1, fp_one());
}

void (*fp_two)(void** state) = null_test_success;

int main(void) {
    const struct CMUnitTest tests[] = {
        cmocka_unit_test(null_test_success),
        cmocka_unit_test(fp),
        cmocka_unit_test(two_test_success),
    };
    return cmocka_run_group_tests(tests, NULL, NULL);
}

// Starting with example at https://api.cmocka.org/index.html (A Cmocka test)
// purpose is to test various usage of function pointers in Cmocka API

// g++ -o demo_segfault -lcmocka demo_segfault.c -lcmocka

extern "C" {

#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>

/* A test case that does nothing and succeeds. */
static void null_test_success(void **state) {
    (void) state; /* unused */
}

void (*fp)(void** state) = null_test_success;

/* Perform two tests that should succeed */
static int ret_one(int a) {
    return 1;
}
int (*fp_one)(int) = ret_one;

static void two_test_success(void **state) {
    (void) state; /* unused */
    assert_int_equal(1, ret_one(1));
    assert_int_equal(1, fp_one(1));
}

void (*fp_two)(void** state) = null_test_success;

int main(void) {
    const struct CMUnitTest tests[] = {
        cmocka_unit_test(null_test_success),
        cmocka_unit_test(fp),
        cmocka_unit_test(two_test_success),
    };
    return cmocka_run_group_tests(tests, NULL, NULL);
}

}