PostgreSQL: ereport 函数在退出前不清栈
PostgreSQL: The ereport function does not clear the stack before exiting
我正试图退出该函数并出错,但堆栈未被清除。
我写了一个 Foo class 并在析构函数中创建日志。但是,没有任何记录
#pragma once
#include "Logger.h"
inline auto& logger = Logger::getInstance();
extern "C"
{
#include "postgres.h"
#include "fmgr.h"
#include "miscadmin.h"
#include "catalog/pg_authid.h"
#include "utils/syscache.h"
#include "utils/builtins.h"
PG_FUNCTION_INFO_V1(simpleFuntions);
Datum simpleFuntions(PG_FUNCTION_ARGS);
}
test.cpp
#include "test.h"
extern "C"
{
PG_MODULE_MAGIC;
}
class Foo
{
public:
Foo(){logger.log("START");};
~Foo(){logger.log("TEST IS CORRECT!");};
};
Datum simpleFuntions(PG_FUNCTION_ARGS)
{
Foo che;
ereport(ERROR,
(
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
errmsg("ERROR")
)
);
FlushErrorState();
PG_RETURN_TEXT_P(cstring_to_text("HelloWorld"));
}
函数执行后,在日志文件中我只看到“START”。
后端访问的所有函数都必须向后端提供一个C接口;然后这些 C 函数可以调用 C++ 函数。 例如,extern C
函数需要 backend-accessed 链接。
好的,我发现了一个问题。
事实是 postgres 创建了 longjmp 点。因此,当 ereport 发生时,它 returns 堆栈到 longjump 点。因此,不会调用析构函数。
我通过降低 C++ 代码的级别并将其包装在 try, catch 中解决了这个问题。并且已经从 try 中捕获了我调用 ereport 的输出。
另外,我尝试使用带有 palloc 函数的 override new operator 来解决我的问题。但它不像我想要的那样工作。
https://habr.com/ru/post/442058/
可能没有其他解决方案
我正试图退出该函数并出错,但堆栈未被清除。
我写了一个 Foo class 并在析构函数中创建日志。但是,没有任何记录
#pragma once
#include "Logger.h"
inline auto& logger = Logger::getInstance();
extern "C"
{
#include "postgres.h"
#include "fmgr.h"
#include "miscadmin.h"
#include "catalog/pg_authid.h"
#include "utils/syscache.h"
#include "utils/builtins.h"
PG_FUNCTION_INFO_V1(simpleFuntions);
Datum simpleFuntions(PG_FUNCTION_ARGS);
}
test.cpp
#include "test.h"
extern "C"
{
PG_MODULE_MAGIC;
}
class Foo
{
public:
Foo(){logger.log("START");};
~Foo(){logger.log("TEST IS CORRECT!");};
};
Datum simpleFuntions(PG_FUNCTION_ARGS)
{
Foo che;
ereport(ERROR,
(
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
errmsg("ERROR")
)
);
FlushErrorState();
PG_RETURN_TEXT_P(cstring_to_text("HelloWorld"));
}
函数执行后,在日志文件中我只看到“START”。
后端访问的所有函数都必须向后端提供一个C接口;然后这些 C 函数可以调用 C++ 函数。 例如,extern C
函数需要 backend-accessed 链接。
好的,我发现了一个问题。 事实是 postgres 创建了 longjmp 点。因此,当 ereport 发生时,它 returns 堆栈到 longjump 点。因此,不会调用析构函数。 我通过降低 C++ 代码的级别并将其包装在 try, catch 中解决了这个问题。并且已经从 try 中捕获了我调用 ereport 的输出。 另外,我尝试使用带有 palloc 函数的 override new operator 来解决我的问题。但它不像我想要的那样工作。 https://habr.com/ru/post/442058/ 可能没有其他解决方案