Skip to content

Commit 371f2db

Browse files
committed
Add support for runtime arguments in injection points
The macros INJECTION_POINT() and INJECTION_POINT_CACHED() are extended with an optional argument that can be passed down to the callback attached when an injection point is run, giving to callbacks the possibility to manipulate a stack state given by the caller. The existing callbacks in modules injection_points and test_aio have their declarations adjusted based on that. da72269 (core AIO infrastructure) and 93bc3d7 (test_aio) and been relying on a set of workarounds where a static variable called pgaio_inj_cur_handle is used as runtime argument in the injection point callbacks used by the AIO tests, in combination with a TRY/CATCH block to reset the argument value. The infrastructure introduced in this commit will be reused for the AIO tests, simplifying them. Reviewed-by: Greg Burd <greg@burd.me> Discussion: https://postgr.es/m/Z_y9TtnXubvYAApS@paquier.xyz
1 parent 89372d0 commit 371f2db

File tree

23 files changed

+69
-57
lines changed

23 files changed

+69
-57
lines changed

doc/src/sgml/xfunc.sgml

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3829,15 +3829,17 @@ uint32 WaitEventExtensionNew(const char *wait_event_name)
38293829
An injection point with a given <literal>name</literal> is declared using
38303830
macro:
38313831
<programlisting>
3832-
INJECTION_POINT(name);
3832+
INJECTION_POINT(name, arg);
38333833
</programlisting>
38343834

38353835
There are a few injection points already declared at strategic points
38363836
within the server code. After adding a new injection point the code needs
38373837
to be compiled in order for that injection point to be available in the
38383838
binary. Add-ins written in C-language can declare injection points in
3839-
their own code using the same macro. The injection point names should
3840-
use lower-case characters, with terms separated by dashes.
3839+
their own code using the same macro. The injection point names should use
3840+
lower-case characters, with terms separated by
3841+
dashes. <literal>arg</literal> is an optional argument value given to the
3842+
callback at run-time.
38413843
</para>
38423844

38433845
<para>
@@ -3847,7 +3849,7 @@ INJECTION_POINT(name);
38473849
a two-step approach with the following macros:
38483850
<programlisting>
38493851
INJECTION_POINT_LOAD(name);
3850-
INJECTION_POINT_CACHED(name);
3852+
INJECTION_POINT_CACHED(name, arg);
38513853
</programlisting>
38523854

38533855
Before entering the critical section,
@@ -3880,7 +3882,9 @@ extern void InjectionPointAttach(const char *name,
38803882
<literal>InjectionPointCallback</literal>:
38813883
<programlisting>
38823884
static void
3883-
custom_injection_callback(const char *name, const void *private_data)
3885+
custom_injection_callback(const char *name,
3886+
const void *private_data,
3887+
void *arg)
38843888
{
38853889
uint32 wait_event_info = WaitEventInjectionPointNew(name);
38863890

@@ -3909,7 +3913,7 @@ if (IS_INJECTION_POINT_ATTACHED("before-foobar"))
39093913
local_var = 123;
39103914

39113915
/* also execute the callback */
3912-
INJECTION_POINT_CACHED("before-foobar");
3916+
INJECTION_POINT_CACHED("before-foobar", NULL);
39133917
}
39143918
#endif
39153919
</programlisting>

src/backend/access/gin/ginbtree.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -685,9 +685,9 @@ ginFinishSplit(GinBtree btree, GinBtreeStack *stack, bool freestack,
685685

686686
#ifdef USE_INJECTION_POINTS
687687
if (GinPageIsLeaf(BufferGetPage(stack->buffer)))
688-
INJECTION_POINT("gin-leave-leaf-split-incomplete");
688+
INJECTION_POINT("gin-leave-leaf-split-incomplete", NULL);
689689
else
690-
INJECTION_POINT("gin-leave-internal-split-incomplete");
690+
INJECTION_POINT("gin-leave-internal-split-incomplete", NULL);
691691
#endif
692692

693693
/* search parent to lock */
@@ -778,7 +778,7 @@ ginFinishSplit(GinBtree btree, GinBtreeStack *stack, bool freestack,
778778
static void
779779
ginFinishOldSplit(GinBtree btree, GinBtreeStack *stack, GinStatsData *buildStats, int access)
780780
{
781-
INJECTION_POINT("gin-finish-incomplete-split");
781+
INJECTION_POINT("gin-finish-incomplete-split", NULL);
782782
elog(DEBUG1, "finishing incomplete split of block %u in gin index \"%s\"",
783783
stack->blkno, RelationGetRelationName(btree->index));
784784

src/backend/access/heap/heapam.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3304,7 +3304,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
33043304
interesting_attrs = bms_add_members(interesting_attrs, id_attrs);
33053305

33063306
block = ItemPointerGetBlockNumber(otid);
3307-
INJECTION_POINT("heap_update-before-pin");
3307+
INJECTION_POINT("heap_update-before-pin", NULL);
33083308
buffer = ReadBuffer(relation, block);
33093309
page = BufferGetPage(buffer);
33103310

src/backend/access/index/genam.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -851,7 +851,7 @@ systable_inplace_update_begin(Relation relation,
851851
if (retries++ > 10000)
852852
elog(ERROR, "giving up after too many tries to overwrite row");
853853

854-
INJECTION_POINT("inplace-before-pin");
854+
INJECTION_POINT("inplace-before-pin", NULL);
855855
scan = systable_beginscan(relation, indexId, indexOK, snapshot,
856856
nkeys, unconstify(ScanKeyData *, key));
857857
oldtup = systable_getnext(scan);

src/backend/access/transam/multixact.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -872,7 +872,7 @@ MultiXactIdCreateFromMembers(int nmembers, MultiXactMember *members)
872872
*/
873873
multi = GetNewMultiXactId(nmembers, &offset);
874874

875-
INJECTION_POINT_CACHED("multixact-create-from-members");
875+
INJECTION_POINT_CACHED("multixact-create-from-members", NULL);
876876

877877
/* Make an XLOG entry describing the new MXID. */
878878
xlrec.mid = multi;
@@ -1486,7 +1486,7 @@ GetMultiXactIdMembers(MultiXactId multi, MultiXactMember **members,
14861486
LWLockRelease(lock);
14871487
CHECK_FOR_INTERRUPTS();
14881488

1489-
INJECTION_POINT("multixact-get-members-cv-sleep");
1489+
INJECTION_POINT("multixact-get-members-cv-sleep", NULL);
14901490

14911491
ConditionVariableSleep(&MultiXactState->nextoff_cv,
14921492
WAIT_EVENT_MULTIXACT_CREATION);

src/backend/access/transam/xlog.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7882,7 +7882,7 @@ CreateRestartPoint(int flags)
78827882
* This location needs to be after CheckPointGuts() to ensure that some
78837883
* work has already happened during this checkpoint.
78847884
*/
7885-
INJECTION_POINT("create-restart-point");
7885+
INJECTION_POINT("create-restart-point", NULL);
78867886

78877887
/*
78887888
* Remember the prior checkpoint's redo ptr for

src/backend/commands/indexcmds.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3892,9 +3892,9 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein
38923892

38933893
#ifdef USE_INJECTION_POINTS
38943894
if (idx->safe)
3895-
INJECTION_POINT("reindex-conc-index-safe");
3895+
INJECTION_POINT("reindex-conc-index-safe", NULL);
38963896
else
3897-
INJECTION_POINT("reindex-conc-index-not-safe");
3897+
INJECTION_POINT("reindex-conc-index-not-safe", NULL);
38983898
#endif
38993899

39003900
idx->tableId = RelationGetRelid(heapRel);

src/backend/executor/nodeAgg.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1492,7 +1492,7 @@ build_hash_tables(AggState *aggstate)
14921492
if (IS_INJECTION_POINT_ATTACHED("hash-aggregate-oversize-table"))
14931493
{
14941494
nbuckets = memory / TupleHashEntrySize();
1495-
INJECTION_POINT_CACHED("hash-aggregate-oversize-table");
1495+
INJECTION_POINT_CACHED("hash-aggregate-oversize-table", NULL);
14961496
}
14971497
#endif
14981498

@@ -1882,7 +1882,7 @@ hash_agg_check_limits(AggState *aggstate)
18821882
if (IS_INJECTION_POINT_ATTACHED("hash-aggregate-spill-1000"))
18831883
{
18841884
do_spill = true;
1885-
INJECTION_POINT_CACHED("hash-aggregate-spill-1000");
1885+
INJECTION_POINT_CACHED("hash-aggregate-spill-1000", NULL);
18861886
}
18871887
}
18881888
#endif
@@ -1910,7 +1910,7 @@ hash_agg_check_limits(AggState *aggstate)
19101910
static void
19111911
hash_agg_enter_spill_mode(AggState *aggstate)
19121912
{
1913-
INJECTION_POINT("hash-aggregate-enter-spill-mode");
1913+
INJECTION_POINT("hash-aggregate-enter-spill-mode", NULL);
19141914
aggstate->hash_spill_mode = true;
19151915
hashagg_recompile_expressions(aggstate, aggstate->table_filled, true);
19161916

@@ -2739,7 +2739,7 @@ agg_refill_hash_table(AggState *aggstate)
27392739
*/
27402740
hashagg_recompile_expressions(aggstate, true, true);
27412741

2742-
INJECTION_POINT("hash-aggregate-process-batch");
2742+
INJECTION_POINT("hash-aggregate-process-batch", NULL);
27432743
for (;;)
27442744
{
27452745
TupleTableSlot *spillslot = aggstate->hash_spill_rslot;
@@ -2995,7 +2995,7 @@ hashagg_spill_init(HashAggSpill *spill, LogicalTapeSet *tapeset, int used_bits,
29952995
{
29962996
npartitions = 1;
29972997
partition_bits = 0;
2998-
INJECTION_POINT_CACHED("hash-aggregate-single-partition");
2998+
INJECTION_POINT_CACHED("hash-aggregate-single-partition", NULL);
29992999
}
30003000
#endif
30013001

src/backend/libpq/be-secure-gssapi.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,7 @@ secure_open_gssapi(Port *port)
500500
minor;
501501
gss_cred_id_t delegated_creds;
502502

503-
INJECTION_POINT("backend-gssapi-startup");
503+
INJECTION_POINT("backend-gssapi-startup", NULL);
504504

505505
/*
506506
* Allocate subsidiary Port data for GSSAPI operations.

src/backend/libpq/be-secure.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ secure_open_server(Port *port)
131131
}
132132
Assert(pq_buffer_remaining_data() == 0);
133133

134-
INJECTION_POINT("backend-ssl-startup");
134+
INJECTION_POINT("backend-ssl-startup", NULL);
135135

136136
r = be_tls_open_server(port);
137137

src/backend/postmaster/autovacuum.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1922,7 +1922,7 @@ do_autovacuum(void)
19221922
* This injection point is put in a transaction block to work with a wait
19231923
* that uses a condition variable.
19241924
*/
1925-
INJECTION_POINT("autovacuum-worker-start");
1925+
INJECTION_POINT("autovacuum-worker-start", NULL);
19261926

19271927
/*
19281928
* Compute the multixact age for which freezing is urgent. This is

src/backend/storage/aio/aio.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1275,7 +1275,7 @@ pgaio_io_call_inj(PgAioHandle *ioh, const char *injection_point)
12751275

12761276
PG_TRY();
12771277
{
1278-
InjectionPointCached(injection_point);
1278+
InjectionPointCached(injection_point, NULL);
12791279
}
12801280
PG_FINALLY();
12811281
{

src/backend/tcop/backend_startup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ BackendInitialize(ClientSocket *client_sock, CAC_state cac)
234234

235235
/* For testing client error handling */
236236
#ifdef USE_INJECTION_POINTS
237-
INJECTION_POINT("backend-initialize");
237+
INJECTION_POINT("backend-initialize", NULL);
238238
if (IS_INJECTION_POINT_ATTACHED("backend-initialize-v2-error"))
239239
{
240240
/*

src/backend/tcop/postgres.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3482,7 +3482,7 @@ ProcessInterrupts(void)
34823482
IdleInTransactionSessionTimeoutPending = false;
34833483
if (IdleInTransactionSessionTimeout > 0)
34843484
{
3485-
INJECTION_POINT("idle-in-transaction-session-timeout");
3485+
INJECTION_POINT("idle-in-transaction-session-timeout", NULL);
34863486
ereport(FATAL,
34873487
(errcode(ERRCODE_IDLE_IN_TRANSACTION_SESSION_TIMEOUT),
34883488
errmsg("terminating connection due to idle-in-transaction timeout")));
@@ -3495,7 +3495,7 @@ ProcessInterrupts(void)
34953495
TransactionTimeoutPending = false;
34963496
if (TransactionTimeout > 0)
34973497
{
3498-
INJECTION_POINT("transaction-timeout");
3498+
INJECTION_POINT("transaction-timeout", NULL);
34993499
ereport(FATAL,
35003500
(errcode(ERRCODE_TRANSACTION_TIMEOUT),
35013501
errmsg("terminating connection due to transaction timeout")));
@@ -3508,7 +3508,7 @@ ProcessInterrupts(void)
35083508
IdleSessionTimeoutPending = false;
35093509
if (IdleSessionTimeout > 0)
35103510
{
3511-
INJECTION_POINT("idle-session-timeout");
3511+
INJECTION_POINT("idle-session-timeout", NULL);
35123512
ereport(FATAL,
35133513
(errcode(ERRCODE_IDLE_SESSION_TIMEOUT),
35143514
errmsg("terminating connection due to idle-session timeout")));

src/backend/utils/cache/catcache.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1926,7 +1926,7 @@ SearchCatCacheList(CatCache *cache,
19261926
/* Injection point to help testing the recursive invalidation case */
19271927
if (first_iter)
19281928
{
1929-
INJECTION_POINT("catcache-list-miss-systable-scan-started");
1929+
INJECTION_POINT("catcache-list-miss-systable-scan-started", NULL);
19301930
first_iter = false;
19311931
}
19321932

src/backend/utils/cache/inval.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1207,7 +1207,7 @@ AtEOXact_Inval(bool isCommit)
12071207
/* Must be at top of stack */
12081208
Assert(transInvalInfo->my_level == 1 && transInvalInfo->parent == NULL);
12091209

1210-
INJECTION_POINT("transaction-end-process-inval");
1210+
INJECTION_POINT("transaction-end-process-inval", NULL);
12111211

12121212
if (isCommit)
12131213
{

src/backend/utils/cache/typcache.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -952,7 +952,7 @@ lookup_type_cache(Oid type_id, int flags)
952952
load_domaintype_info(typentry);
953953
}
954954

955-
INJECTION_POINT("typecache-before-rel-type-cache-insert");
955+
INJECTION_POINT("typecache-before-rel-type-cache-insert", NULL);
956956

957957
Assert(in_progress_offset + 1 == in_progress_list_len);
958958
in_progress_list_len--;

src/backend/utils/init/postinit.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,7 @@ InitPostgres(const char *in_dbname, Oid dboid,
747747
if (!bootstrap)
748748
{
749749
pgstat_bestart_initial();
750-
INJECTION_POINT("init-pre-auth");
750+
INJECTION_POINT("init-pre-auth", NULL);
751751
}
752752

753753
/*

src/backend/utils/misc/injection_point.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -541,14 +541,14 @@ InjectionPointLoad(const char *name)
541541
* Execute an injection point, if defined.
542542
*/
543543
void
544-
InjectionPointRun(const char *name)
544+
InjectionPointRun(const char *name, void *arg)
545545
{
546546
#ifdef USE_INJECTION_POINTS
547547
InjectionPointCacheEntry *cache_entry;
548548

549549
cache_entry = InjectionPointCacheRefresh(name);
550550
if (cache_entry)
551-
cache_entry->callback(name, cache_entry->private_data);
551+
cache_entry->callback(name, cache_entry->private_data, arg);
552552
#else
553553
elog(ERROR, "Injection points are not supported by this build");
554554
#endif
@@ -558,14 +558,14 @@ InjectionPointRun(const char *name)
558558
* Execute an injection point directly from the cache, if defined.
559559
*/
560560
void
561-
InjectionPointCached(const char *name)
561+
InjectionPointCached(const char *name, void *arg)
562562
{
563563
#ifdef USE_INJECTION_POINTS
564564
InjectionPointCacheEntry *cache_entry;
565565

566566
cache_entry = injection_point_cache_get(name);
567567
if (cache_entry)
568-
cache_entry->callback(name, cache_entry->private_data);
568+
cache_entry->callback(name, cache_entry->private_data, arg);
569569
#else
570570
elog(ERROR, "Injection points are not supported by this build");
571571
#endif

src/include/utils/injection_point.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,22 @@
1616
*/
1717
#ifdef USE_INJECTION_POINTS
1818
#define INJECTION_POINT_LOAD(name) InjectionPointLoad(name)
19-
#define INJECTION_POINT(name) InjectionPointRun(name)
20-
#define INJECTION_POINT_CACHED(name) InjectionPointCached(name)
19+
#define INJECTION_POINT(name, arg) InjectionPointRun(name, arg)
20+
#define INJECTION_POINT_CACHED(name, arg) InjectionPointCached(name, arg)
2121
#define IS_INJECTION_POINT_ATTACHED(name) IsInjectionPointAttached(name)
2222
#else
2323
#define INJECTION_POINT_LOAD(name) ((void) name)
24-
#define INJECTION_POINT(name) ((void) name)
25-
#define INJECTION_POINT_CACHED(name) ((void) name)
24+
#define INJECTION_POINT(name, arg) ((void) name)
25+
#define INJECTION_POINT_CACHED(name, arg) ((void) name)
2626
#define IS_INJECTION_POINT_ATTACHED(name) (false)
2727
#endif
2828

2929
/*
3030
* Typedef for callback function launched by an injection point.
3131
*/
3232
typedef void (*InjectionPointCallback) (const char *name,
33-
const void *private_data);
33+
const void *private_data,
34+
void *arg);
3435

3536
extern Size InjectionPointShmemSize(void);
3637
extern void InjectionPointShmemInit(void);
@@ -41,8 +42,8 @@ extern void InjectionPointAttach(const char *name,
4142
const void *private_data,
4243
int private_data_size);
4344
extern void InjectionPointLoad(const char *name);
44-
extern void InjectionPointRun(const char *name);
45-
extern void InjectionPointCached(const char *name);
45+
extern void InjectionPointRun(const char *name, void *arg);
46+
extern void InjectionPointCached(const char *name, void *arg);
4647
extern bool IsInjectionPointAttached(const char *name);
4748
extern bool InjectionPointDetach(const char *name);
4849

0 commit comments

Comments
 (0)