Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Как узнать, кто вызвал функцию? / 25 сообщений из 33, страница 1 из 2
16.07.2018, 07:56
    #39674326
Ролг Хупин
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как узнать, кто вызвал функцию?
(Mac OS X)
Ловлю пробои при работе с памятью, в частности - попытку повторного free.

Заменил malloc, free на свои обёртки, которые внутр вызвают реальные.
1. Можно ли оболожить вызов free try-catch так, чтобы даже при попытке повторного освобождения приложение не улетало, а просто игнорировало?
2. Как вывести (в стдерр или в файл) стек вызовов, чтобы понять, кто вызывает malloc и free?
...
Рейтинг: 0 / 0
16.07.2018, 09:08
    #39674335
kealon(Ruslan)
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как узнать, кто вызвал функцию?
Ролг Хупин,

во-первых, какой компилятор?


алгоритм простой, раскручиваете стэк, находите по адресу возврата имя функции, показываете.
...
Рейтинг: 0 / 0
16.07.2018, 09:11
    #39674338
kealon(Ruslan)
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как узнать, кто вызвал функцию?
Ролг Хупин,

если весь стек не нужен и есть возможность подменить все malloc, free дефайном, подставьте просто вызовов своей функции с передачей ей номера строки и имени файла
...
Рейтинг: 0 / 0
16.07.2018, 09:58
    #39674383
256k
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как узнать, кто вызвал функцию?
kealon(Ruslan)Ролг Хупин,

если весь стек не нужен и есть возможность подменить все malloc, free дефайном, подставьте просто вызовов своей функции с передачей ей номера строки и имени файла

gcc

Я уже перепрределил, но при таком подходе надо все вызовы переделывать, а это не лучший вариант.
Весь стек и не нужен, по сути нужен непосредственный вызватель маллок и фри
...
Рейтинг: 0 / 0
16.07.2018, 10:07
    #39674388
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как узнать, кто вызвал функцию?
256kЯ уже перепрределил, но при таком подходе надо все вызовы переделывать, а это не лучший вариант.
Весь стек и не нужен, по сути нужен непосредственный вызватель маллок и фри
Все вызовы не надо трогать. Руслан про заменить на макрос
Код: plaintext
1.
#define malloc(X) my_malloc(X, __FILE__, __LINE__)
...
Рейтинг: 0 / 0
16.07.2018, 10:24
    #39674396
kealon(Ruslan)
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как узнать, кто вызвал функцию?
21573315 , ага так
...
Рейтинг: 0 / 0
16.07.2018, 10:42
    #39674405
256k
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как узнать, кто вызвал функцию?
Dima T256kЯ уже перепрределил, но при таком подходе надо все вызовы переделывать, а это не лучший вариант.
Весь стек и не нужен, по сути нужен непосредственный вызватель маллок и фри
Все вызовы не надо трогать. Руслан про заменить на макрос
Код: plaintext
1.
#define malloc(X) my_malloc(X, __FILE__, __LINE__)



а, понял, протупил, это вариант. Он поддерживается на маке?
...
Рейтинг: 0 / 0
16.07.2018, 17:10
    #39674610
256k
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как узнать, кто вызвал функцию?
Dima T256kЯ уже перепрределил, но при таком подходе надо все вызовы переделывать, а это не лучший вариант.
Весь стек и не нужен, по сути нужен непосредственный вызватель маллок и фри
Все вызовы не надо трогать. Руслан про заменить на макрос
Код: plaintext
1.
#define malloc(X) my_malloc(X, __FILE__, __LINE__)




было так
Код: plaintext
1.
#define memcpy   debug_memcpy



сделал так:
Код: plaintext
1.
#define memcpy(X,Y,Z)   debug_memcpy(X,Y,Z,__FILE__,__LINE__)




и для других функций тоже, компилер накидал ошибок

Код: plaintext
1.
2.
3.
4.
5.
6.
In file included from info.c:21:
/usr/include/string.h:72:7: error: conflicting types for 'debug_memcpy'
void    *memcpy(void *__dst, const void *__src, size_t __n);
         ^
23: note: expanded from macro 'memcpy'
#define memcpy(X,Y,Z)   debug_memcpy(X,Y,Z,__FILE__,__LINE__)




что не так сделал?
...
Рейтинг: 0 / 0
16.07.2018, 17:45
    #39674623
kealon(Ruslan)
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как узнать, кто вызвал функцию?
256kбыло так
Код: plaintext
1.
#define memcpy   debug_memcpy



сделал так:
Код: plaintext
1.
#define memcpy(X,Y,Z)   debug_memcpy(X,Y,Z,__FILE__,__LINE__)




и для других функций тоже, компилер накидал ошибок

Код: plaintext
1.
2.
3.
4.
5.
6.
In file included from info.c:21:
/usr/include/string.h:72:7: error: conflicting types for 'debug_memcpy'
void    *memcpy(void *__dst, const void *__src, size_t __n);
         ^
23: note: expanded from macro 'memcpy'
#define memcpy(X,Y,Z)   debug_memcpy(X,Y,Z,__FILE__,__LINE__)




что не так сделал?
было определение
Код: plaintext
1.
void    *memcpy(void *__dst, const void *__src, size_t __n);



стало после подстановки
Код: plaintext
1.
void    *debug_memcpy(void *__dst, const void *__src, size_t __n,__FILE__,__LINE__);
...
Рейтинг: 0 / 0
16.07.2018, 19:17
    #39674652
Ролг Хупин
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как узнать, кто вызвал функцию?
kealon(Ruslan)256kбыло так
Код: plaintext
1.
#define memcpy   debug_memcpy



сделал так:
Код: plaintext
1.
#define memcpy(X,Y,Z)   debug_memcpy(X,Y,Z,__FILE__,__LINE__)




и для других функций тоже, компилер накидал ошибок

Код: plaintext
1.
2.
3.
4.
5.
6.
In file included from info.c:21:
/usr/include/string.h:72:7: error: conflicting types for 'debug_memcpy'
void    *memcpy(void *__dst, const void *__src, size_t __n);
         ^
23: note: expanded from macro 'memcpy'
#define memcpy(X,Y,Z)   debug_memcpy(X,Y,Z,__FILE__,__LINE__)




что не так сделал?
было определение
Код: plaintext
1.
void    *memcpy(void *__dst, const void *__src, size_t __n);



стало после подстановки
Код: plaintext
1.
void    *debug_memcpy(void *__dst, const void *__src, size_t __n,__FILE__,__LINE__);


и как переопределить равильно, чтобы использовать __FILE__,__LINE__ ?
...
Рейтинг: 0 / 0
16.07.2018, 20:05
    #39674669
kealon(Ruslan)
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как узнать, кто вызвал функцию?
Ролг Хупин,

не могу навскидку сказать, я глобально никогда не переопределял

зачем по всем либам переопределять?
...
Рейтинг: 0 / 0
16.07.2018, 20:12
    #39674673
Ролг Хупин
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как узнать, кто вызвал функцию?
kealon(Ruslan)Ролг Хупин,

не могу навскидку сказать, я глобально никогда не переопределял

зачем по всем либам переопределять?

я так понимаю - по всем - это не самоцель, но надо там, где использутся маллок/фри
...
Рейтинг: 0 / 0
16.07.2018, 20:16
    #39674675
Ролг Хупин
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как узнать, кто вызвал функцию?
kealon(Ruslan)Ролг Хупин,

не могу навскидку сказать, я глобально никогда не переопределял

зачем по всем либам переопределять?

хорошо, как в нескольких файлах прожекта переопределить?
...
Рейтинг: 0 / 0
16.07.2018, 20:21
    #39674676
kealon(Ruslan)
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как узнать, кто вызвал функцию?
Ролг Хупинkealon(Ruslan)Ролг Хупин,

не могу навскидку сказать, я глобально никогда не переопределял

зачем по всем либам переопределять?

я так понимаю - по всем - это не самоцель, но надо там, где использутся маллок/фриТогда добавить эти макросы в какой-ни будь общий хидер после включения всех h с "перехватываемыми" определениями и всё. Если нет такого - создать и добавить.
...
Рейтинг: 0 / 0
17.07.2018, 01:10
    #39674732
alexy_black
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как узнать, кто вызвал функцию?
...
Рейтинг: 0 / 0
17.07.2018, 08:34
    #39674806
Ролг Хупин
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как узнать, кто вызвал функцию?
kealon(Ruslan)Ролг Хупинпропущено...


я так понимаю - по всем - это не самоцель, но надо там, где использутся маллок/фриТогда добавить эти макросы в какой-ни будь общий хидер после включения всех h с "перехватываемыми" определениями и всё. Если нет такого - создать и добавить.

ок.
Я так нимаю, что если я хочу переопределить вызовы только в некоторых файлах, тогда лучше изменить вызовы в них.
...
Рейтинг: 0 / 0
17.07.2018, 11:42
    #39674921
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как узнать, кто вызвал функцию?
1. Можно ли оболожить вызов free try-catch так, чтобы даже при попытке повторного освобождения приложение не улетало, а просто игнорировало?

Можно просто проверить, что присланный в free указатель из хипа, и не вызывать настоящий free.
Для этого надо иметь аналог Microsoft-овского IsHeapPointer.

2. Как вывести (в стдерр или в файл) стек вызовов, чтобы понять, кто вызывает malloc и free?

В общем, никак.
Есть Boost::stacktrace правда, но я его не знаю, не могу сказать, при каких условиях он работает.
...
Рейтинг: 0 / 0
17.07.2018, 14:38
    #39675080
semen.s.semen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как узнать, кто вызвал функцию?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
#ifndef _STACKTRACE_H_
#define _STACKTRACE_H_

#include <stdio.h>
#include <stdlib.h>
#include <execinfo.h>
#include <cxxabi.h>

/** Print a demangled stack backtrace of the caller function to FILE* out. */
static inline void print_stacktrace(FILE *out = stderr, unsigned int max_frames = 63) {
    fprintf(out, "stack trace:\n");

    // storage array for stack trace address data
    void *addrlist[max_frames + 1];

    // retrieve current stack addresses
    int aSize = (int)(sizeof(addrlist) / sizeof(void *));
    int addrlen = backtrace(addrlist, aSize);

    if (addrlen == 0) {
        fprintf(out, "  <empty, possibly corrupt>\n");
        return;
    }

    // resolve addresses into strings containing "filename(function+address)",
    // this array must be free()-ed
    char **symbollist = backtrace_symbols(addrlist, addrlen);

    // allocate string which will be filled with the demangled function name
    size_t funcnamesize = 256;
    char *funcname = (char *) malloc(funcnamesize);

    // iterate over the returned symbol lines. skip the first, it is the
    // address of this function.
    for (int i = 1; i < addrlen; i++) {
        char *begin_name = 0, *begin_offset = 0, *end_offset = 0;

        // find parentheses and +address offset surrounding the mangled name:
        // ./module(function+0x15c) [0x8048a6d]
        for (char *p = symbollist[i]; *p; ++p) {
            if (*p == '(')
                begin_name = p;
            else if (*p == '+')
                begin_offset = p;
            else if (*p == ')' && begin_offset) {
                end_offset = p;
                break;
            }
        }

        if (begin_name && begin_offset && end_offset
            && begin_name < begin_offset) {
            *begin_name++ = '\0';
            *begin_offset++ = '\0';
            *end_offset = '\0';

            // mangled name is now in [begin_name, begin_offset) and caller
            // offset in [begin_offset, end_offset). now apply
            // __cxa_demangle():

            int status;
            char *ret = abi::__cxa_demangle(begin_name,
                                            funcname, &funcnamesize, &status);
            if (status == 0) {
                funcname = ret; // use possibly realloc()-ed string
                fprintf(out, "  %s : %s+%s\n",
                        symbollist[i], funcname, begin_offset);
            } else {
                // demangling failed. Output function name as a C function with
                // no arguments.
                fprintf(out, "  %s : %s()+%s\n",
                        symbollist[i], begin_name, begin_offset);
            }
        } else {
            // couldn't parse the line? print the whole line.
            fprintf(out, "  %s\n", symbollist[i]);
        }
    }

    free(funcname);
    free(symbollist);
}

#endif // _STACKTRACE_H_
...
Рейтинг: 0 / 0
19.07.2018, 12:21
    #39676143
256k
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как узнать, кто вызвал функцию?
2 semen.s.semen

Интересный вариант! на макосе это соберется, будет работать?
...
Рейтинг: 0 / 0
19.07.2018, 13:33
    #39676171
256k
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как узнать, кто вызвал функцию?
256k2 semen.s.semen

Интересный вариант! на макосе это соберется, будет работать?
Попытался собрать на маке, сыпется


log.c:95:47: error: C does not support default arguments
static inline void print_stacktrace(FILE *out = stderr, unsigned int max...
^ ~~~~~~
log.c:95:81: error: C does not support default arguments
...print_stacktrace(FILE *out = stderr, unsigned int max_frames = 63) {
^ ~~
log.c:147:25: error: use of undeclared identifier 'abi'; did you mean 'abs'?
char *ret = abi::__cxa_demangle(begin_name,
^~~
abs
/usr/include/stdlib.h:137:6: note: 'abs' declared here
int abs(int) __pure2;
^
log.c:147:19: warning: incompatible pointer types initializing 'char *' with
an expression of type 'int (int)' [-Wincompatible-pointer-types]
char *ret = abi::__cxa_demangle(begin_name,
^ ~~~
log.c:147:28: error: expected ';' at end of declaration
char *ret = abi::__cxa_demangle(begin_name,
^
;
log.c:147:29: error: expected expression
char *ret = abi::__cxa_demangle(begin_name,
...
Рейтинг: 0 / 0
19.07.2018, 14:15
    #39676189
semen.s.semen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как узнать, кто вызвал функцию?
А меня на макосе все собирается )
...
Рейтинг: 0 / 0
19.07.2018, 14:15
    #39676190
semen.s.semen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как узнать, кто вызвал функцию?
это С++ если что не С
...
Рейтинг: 0 / 0
19.07.2018, 18:24
    #39676426
256k
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как узнать, кто вызвал функцию?
semen.s.semenэто С++ если что не С


может из-за этого, это у меня PostgreSQL odbc драйвер
...
Рейтинг: 0 / 0
19.07.2018, 18:26
    #39676430
256k
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как узнать, кто вызвал функцию?
semen.s.semenэто С++ если что не С

вот исходники, может не с++

https://git.postgresql.org/gitweb/?p=psqlodbc.git
...
Рейтинг: 0 / 0
19.07.2018, 21:00
    #39676489
Barlone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как узнать, кто вызвал функцию?
256ksemen.s.semenэто С++ если что не С


может из-за этого, это у меня PostgreSQL odbc драйвертак выкиньте лишнее - дефолтное значение аргумента, demangle...
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Как узнать, кто вызвал функцию? / 25 сообщений из 33, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]