(Thumbnails): Minor cleanup.
[emacs.git] / src / .gdbinit
blob12a9d01402663af6d879ad244d0f11e491dfe8f4
1 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2001,
2 #   2004, 2005, 2006 Free Software Foundation, Inc.
4 # This file is part of GNU Emacs.
6 # GNU Emacs is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2, or (at your option)
9 # any later version.
11 # GNU Emacs is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with GNU Emacs; see the file COPYING.  If not, write to the
18 # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 # Boston, MA 02110-1301, USA.
21 # Force loading of symbols, enough to give us gdb_valbits etc.
22 set main
24 # Find lwlib source files too.
25 dir ../lwlib
26 #dir /gd/gnu/lesstif-0.89.9/lib/Xm
28 # Don't enter GDB when user types C-g to quit.
29 # This has one unfortunate effect: you can't type C-c
30 # at the GDB to stop Emacs, when using X.
31 # However, C-z works just as well in that case.
32 handle 2 noprint pass
34 # Make it work like SIGINT normally does.
35 handle SIGTSTP nopass
37 # Don't pass SIGALRM to Emacs.  This makes problems when
38 # debugging.
39 handle SIGALRM ignore
41 # $valmask and $tagmask are mask values set up by the xreload macro below.
43 # Use $bugfix so that the value isn't a constant.
44 # Using a constant runs into GDB bugs sometimes.
45 define xgetptr
46   set $bugfix = $arg0
47   set $ptr = (gdb_use_union ? $bugfix.u.val : $bugfix & $valmask) | gdb_data_seg_bits
48 end
50 define xgetint
51   set $bugfix = $arg0
52   set $int = gdb_use_union ? $bugfix.s.val : (gdb_use_lsb ? $bugfix : $bugfix << gdb_gctypebits) >> gdb_gctypebits
53 end
55 define xgettype
56   set $bugfix = $arg0
57   set $type = gdb_use_union ? $bugfix.s.type : (enum Lisp_Type) (gdb_use_lsb ? $bugfix & $tagmask : $bugfix >> gdb_valbits)
58 end
60 # Set up something to print out s-expressions.
61 # We save and restore print_output_debug_flag to prevent the w32 port
62 # from calling OutputDebugString, which causes GDB to display each
63 # character twice (yuk!).
64 define pr
65   set $output_debug = print_output_debug_flag
66   set print_output_debug_flag = 0
67   set debug_print ($)
68   set print_output_debug_flag = $output_debug
69 end
70 document pr
71 Print the emacs s-expression which is $.
72 Works only when an inferior emacs is executing.
73 end
75 # Print out s-expressions
76 define pp
77   set $tmp = $arg0
78   set $output_debug = print_output_debug_flag
79   set print_output_debug_flag = 0
80   set safe_debug_print ($tmp)
81   set print_output_debug_flag = $output_debug
82 end
83 document pp
84 Print the argument as an emacs s-expression
85 Works only when an inferior emacs is executing.
86 end
88 # Print out s-expressions from tool bar
89 define pp1
90   set $tmp = $arg0
91   echo $arg0
92   printf " = "
93   set $output_debug = print_output_debug_flag
94   set print_output_debug_flag = 0
95   set safe_debug_print ($tmp)
96   set print_output_debug_flag = $output_debug
97 end
98 document pp1
99 Print the argument as an emacs s-expression
100 Works only when an inferior emacs is executing.
101 For use on tool bar when debugging in Emacs
102 where the variable name would not otherwise
103 be recorded in the GUD buffer.
106 # Print value of lisp variable
107 define pv
108   set $tmp = "$arg0"
109   set $output_debug = print_output_debug_flag
110   set print_output_debug_flag = 0
111   set safe_debug_print ( find_symbol_value (intern ($tmp)))
112   set print_output_debug_flag = $output_debug
114 document pv
115 Print the value of the lisp variable given as argument.
116 Works only when an inferior emacs is executing.
119 # Print value of lisp variable
120 define pv1
121   set $tmp = "$arg0"
122   echo $arg0
123   printf " = "
124   set $output_debug = print_output_debug_flag
125   set print_output_debug_flag = 0
126   set safe_debug_print (find_symbol_value (intern ($tmp)))
127   set print_output_debug_flag = $output_debug
129 document pv1
130 Print the value of the lisp variable given as argument.
131 Works only when an inferior emacs is executing.
132 For use on tool bar when debugging in Emacs
133 where the variable name would not otherwise
134 be recorded in the GUD buffer.
137 # Print out current buffer point and boundaries
138 define ppt
139   set $b = current_buffer
140   set $t = $b->text
141   printf "BUF PT: %d", $b->pt
142   if ($b->pt != $b->pt_byte)
143     printf "[%d]", $b->pt_byte
144   end
145   printf " of 1..%d", $t->z
146   if ($t->z != $t->z_byte)
147     printf "[%d]", $t->z_byte
148   end
149   if ($b->begv != 1 || $b->zv != $t->z)
150     printf " NARROW=%d..%d", $b->begv, $b->zv
151     if ($b->begv != $b->begv_byte || $b->zv != $b->zv_byte)
152       printf " [%d..%d]", $b->begv_byte, $b->zv_byte
153     end
154   end
155   printf " GAP: %d", $t->gpt
156   if ($t->gpt != $t->gpt_byte)
157     printf "[%d]", $t->gpt_byte
158   end
159   printf " SZ=%d\n", $t->gap_size
161 document ppt
162 Print point, beg, end, narrow, and gap for current buffer.
165 # Print out iterator given as first arg
166 define pitx
167   set $it = $arg0
168   printf "cur=%d", $it->current.pos.charpos
169   if ($it->current.pos.charpos != $it->current.pos.bytepos)
170     printf "[%d]", $it->current.pos.bytepos
171   end
172   printf " start=%d", $it->start.pos.charpos
173   if ($it->start.pos.charpos != $it->start.pos.bytepos)
174     printf "[%d]", $it->start.pos.bytepos
175   end
176   printf " end=%d", $it->end_charpos
177   printf " stop=%d", $it->stop_charpos
178   printf " face=%d", $it->face_id
179   if ($it->multibyte_p)
180     printf " MB"
181   end
182   if ($it->header_line_p)
183     printf " HL"
184   end
185   if ($it->n_overlay_strings > 0)
186     printf " nov=%d", $it->n_overlay_strings
187   end
188   if ($it->sp != 0)
189     printf " sp=%d", $it->sp
190   end
191   if ($it->what == IT_CHARACTER)
192     if ($it->len == 1 && $it->c >= ' ' && it->c < 255)
193       printf " ch='%c'", $it->c
194     else
195       printf " ch=[%d,%d]", $it->c, $it->len
196     end
197   else
198     if ($it->what == IT_IMAGE)
199       printf " IMAGE=%d", $it->image_id
200     else
201       printf " "
202       output $it->what
203     end
204   end
205   if ($it->method != GET_FROM_BUFFER)
206     printf " next="
207     output $it->method
208     if ($it->method == GET_FROM_STRING)
209       printf "[%d]", $it->current.string_pos.charpos
210     end
211   end
212   printf "\n"
213   if ($it->region_beg_charpos >= 0)
214     printf "reg=%d-%d ", $it->region_beg_charpos, $it->region_end_charpos
215   end
216   printf "vpos=%d hpos=%d", $it->vpos, $it->hpos,
217   printf " y=%d lvy=%d", $it->current_y, $it->last_visible_y
218   printf " x=%d vx=%d-%d", $it->current_x, $it->first_visible_x, $it->last_visible_x
219   printf " a+d=%d+%d=%d", $it->ascent, $it->descent, $it->ascent+$it->descent
220   printf " max=%d+%d=%d", $it->max_ascent, $it->max_descent, $it->max_ascent+$it->max_descent
221   printf "\n"
223 document pitx
224 Pretty print a display iterator.
225 Take one arg, an iterator object or pointer.
228 define pit
229   pitx it
231 document pit
232 Pretty print the display iterator it.
235 define prowx
236   set $row = $arg0
237   printf "y=%d x=%d pwid=%d", $row->y, $row->x, $row->pixel_width
238   printf " a+d=%d+%d=%d", $row->ascent, $row->height-$row->ascent, $row->height
239   printf " phys=%d+%d=%d", $row->phys_ascent, $row->phys_height-$row->phys_ascent, $row->phys_height
240   printf " vis=%d", $row->visible_height
241   printf "  L=%d T=%d R=%d", $row->used[0], $row->used[1], $row->used[2]
242   printf "\n"
243   printf "start=%d end=%d", $row->start.pos.charpos, $row->end.pos.charpos
244   if ($row->enabled_p)
245     printf " ENA"
246   end
247   if ($row->displays_text_p)
248     printf " DISP"
249   end
250   if ($row->mode_line_p)
251     printf " MODEL"
252   end
253   if ($row->continued_p)
254     printf " CONT"
255   end
256   if ($row-> truncated_on_left_p)
257     printf " TRUNC:L"
258   end
259   if ($row-> truncated_on_right_p)
260     printf " TRUNC:R"
261   end
262   if ($row->starts_in_middle_of_char_p)
263     printf " STARTMID"
264   end
265   if ($row->ends_in_middle_of_char_p)
266     printf " ENDMID"
267   end
268   if ($row->ends_in_newline_from_string_p)
269     printf " ENDNLFS"
270   end
271   if ($row->ends_at_zv_p)
272     printf " ENDZV"
273   end
274   if ($row->overlapped_p)
275     printf " OLAPD"
276   end
277   if ($row->overlapping_p)
278     printf " OLAPNG"
279   end
280   printf "\n"
282 document prowx
283 Pretty print information about glyph_row.
284 Takes one argument, a row object or pointer.
287 define prow
288   prowx row
290 document prow
291 Pretty print information about glyph_row in row.
295 define pcursorx
296   set $cp = $arg0
297   printf "y=%d x=%d vpos=%d hpos=%d", $cp->y, $cp->x, $cp->vpos, $cp->hpos
299 document pcursorx
300 Pretty print a window cursor
303 define pcursor
304   printf "output: "
305   pcursorx output_cursor
306   printf "\n"
308 document pcursor
309 Pretty print the output_cursor
312 define pwinx
313   set $w = $arg0
314   xgetint $w->sequence_number
315   if ($w->mini_p != Qnil)
316     printf "Mini "
317   end
318   printf "Window %d ", $int
319   xgetptr $w->buffer
320   set $tem = (struct buffer *) $ptr
321   xgetptr $tem->name
322   printf "%s", ((struct Lisp_String *) $ptr)->data
323   printf "\n"
324   xgetptr $w->start
325   set $tem = (struct Lisp_Marker *) $ptr
326   printf "start=%d end:", $tem->charpos
327   if ($w->window_end_valid != Qnil)
328     xgetint $w->window_end_pos
329     printf "pos=%d", $int
330     xgetint $w->window_end_vpos
331     printf " vpos=%d", $int
332   else
333     printf "invalid"
334   end
335   printf " vscroll=%d", $w->vscroll
336   if ($w->force_start != Qnil)
337     printf " FORCE_START"
338   end
339   if ($w->must_be_updated_p)
340     printf " MUST_UPD"
341   end
342   printf "\n"
343   printf "cursor: "
344   pcursorx $w->cursor
345   printf "  phys: "
346   pcursorx $w->phys_cursor
347   if ($w->phys_cursor_on_p)
348     printf " ON"
349   else
350     printf " OFF"
351   end
352   printf " blk="
353   if ($w->last_cursor_off_p != $w->cursor_off_p)
354     if ($w->last_cursor_off_p)
355       printf "ON->"
356     else
357       printf "OFF->"
358     end
359   end
360   if ($w->cursor_off_p)
361     printf "ON"
362   else
363     printf "OFF"
364   end
365   printf "\n"
367 document pwinx
368 Pretty print a window structure.
369 Takes one argument, a pointer to a window structure
372 define pwin
373   pwinx w
375 document pwin
376 Pretty print window structure w.
380 define xtype
381   xgettype $
382   output $type
383   echo \n
384   if $type == Lisp_Misc
385     xmisctype
386   else
387     if $type == Lisp_Vectorlike
388       xvectype
389     end
390   end
392 document xtype
393 Print the type of $, assuming it is an Emacs Lisp value.
394 If the first type printed is Lisp_Vector or Lisp_Misc,
395 a second line gives the more precise type.
398 define xvectype
399   xgetptr $
400   set $size = ((struct Lisp_Vector *) $ptr)->size
401   output ($size & PVEC_FLAG) ? (enum pvec_type) ($size & PVEC_TYPE_MASK) : $size & ~gdb_array_mark_flag
402   echo \n
404 document xvectype
405 Print the size or vector subtype of $, assuming it is a vector or pseudovector.
408 define xmisctype
409   xgetptr $
410   output (enum Lisp_Misc_Type) (((struct Lisp_Free *) $ptr)->type)
411   echo \n
413 document xmisctype
414 Print the specific type of $, assuming it is some misc type.
417 define xint
418   xgetint $
419   print $int
421 document xint
422 Print $, assuming it is an Emacs Lisp integer.  This gets the sign right.
425 define xptr
426   xgetptr $
427   print (void *) $ptr
429 document xptr
430 Print the pointer portion of $, assuming it is an Emacs Lisp value.
433 define xmarker
434   xgetptr $
435   print (struct Lisp_Marker *) $ptr
437 document xmarker
438 Print $ as a marker pointer, assuming it is an Emacs Lisp marker value.
441 define xoverlay
442   xgetptr $
443   print (struct Lisp_Overlay *) $ptr
445 document xoverlay
446 Print $ as a overlay pointer, assuming it is an Emacs Lisp overlay value.
449 define xmiscfree
450   xgetptr $
451   print (struct Lisp_Free *) $ptr
453 document xmiscfree
454 Print $ as a misc free-cell pointer, assuming it is an Emacs Lisp Misc value.
457 define xintfwd
458   xgetptr $
459   print (struct Lisp_Intfwd *) $ptr
461 document xintfwd
462 Print $ as an integer forwarding pointer, assuming it is an Emacs Lisp Misc value.
465 define xboolfwd
466   xgetptr $
467   print (struct Lisp_Boolfwd *) $ptr
469 document xboolfwd
470 Print $ as a boolean forwarding pointer, assuming it is an Emacs Lisp Misc value.
473 define xobjfwd
474   xgetptr $
475   print (struct Lisp_Objfwd *) $ptr
477 document xobjfwd
478 Print $ as an object forwarding pointer, assuming it is an Emacs Lisp Misc value.
481 define xbufobjfwd
482   xgetptr $
483   print (struct Lisp_Buffer_Objfwd *) $ptr
485 document xbufobjfwd
486 Print $ as a buffer-local object forwarding pointer, assuming it is an Emacs Lisp Misc value.
489 define xkbobjfwd
490   xgetptr $
491   print (struct Lisp_Kboard_Objfwd *) $ptr
493 document xkbobjfwd
494 Print $ as a kboard-local object forwarding pointer, assuming it is an Emacs Lisp Misc value.
497 define xbuflocal
498   xgetptr $
499   print (struct Lisp_Buffer_Local_Value *) $ptr
501 document xbuflocal
502 Print $ as a buffer-local-value pointer, assuming it is an Emacs Lisp Misc value.
505 define xsymbol
506   set $sym = $
507   xgetptr $sym
508   print (struct Lisp_Symbol *) $ptr
509   xprintsym $sym
510   echo \n
512 document xsymbol
513 Print the name and address of the symbol $.
514 This command assumes that $ is an Emacs Lisp symbol value.
517 define xstring
518   xgetptr $
519   print (struct Lisp_String *) $ptr
520   xprintstr $
521   echo \n
523 document xstring
524 Print the contents and address of the string $.
525 This command assumes that $ is an Emacs Lisp string value.
528 define xvector
529   xgetptr $
530   print (struct Lisp_Vector *) $ptr
531   output ($->size > 50) ? 0 : ($->contents[0])@($->size & ~gdb_array_mark_flag)
532 echo \n
534 document xvector
535 Print the contents and address of the vector $.
536 This command assumes that $ is an Emacs Lisp vector value.
539 define xprocess
540   xgetptr $
541   print (struct Lisp_Process *) $ptr
542   output *$
543   echo \n
545 document xprocess
546 Print the address of the struct Lisp_process which the Lisp_Object $ points to.
549 define xframe
550   xgetptr $
551   print (struct frame *) $ptr
553 document xframe
554 Print $ as a frame pointer, assuming it is an Emacs Lisp frame value.
557 define xcompiled
558   xgetptr $
559   print (struct Lisp_Vector *) $ptr
560   output ($->contents[0])@($->size & 0xff)
562 document xcompiled
563 Print $ as a compiled function pointer, assuming it is an Emacs Lisp compiled value.
566 define xwindow
567   xgetptr $
568   print (struct window *) $ptr
569   set $window = (struct window *) $ptr
570   xgetint $window->total_cols
571   set $width=$int
572   xgetint $window->total_lines
573   set $height=$int
574   xgetint $window->left_col
575   set $left=$int
576   xgetint $window->top_line
577   set $top=$int
578   printf "%dx%d+%d+%d\n", $width, $height, $left, $top
580 document xwindow
581 Print $ as a window pointer, assuming it is an Emacs Lisp window value.
582 Print the window's position as "WIDTHxHEIGHT+LEFT+TOP".
585 define xwinconfig
586   xgetptr $
587   print (struct save_window_data *) $ptr
589 document xwinconfig
590 Print $ as a window configuration pointer, assuming it is an Emacs Lisp window configuration value.
593 define xsubr
594   xgetptr $
595   print (struct Lisp_Subr *) $ptr
596   output *$
597   echo \n
599 document xsubr
600 Print the address of the subr which the Lisp_Object $ points to.
603 define xchartable
604   xgetptr $
605   print (struct Lisp_Char_Table *) $ptr
606   printf "Purpose: "
607   xprintsym $->purpose
608   printf "  %d extra slots", ($->size & 0x1ff) - 388
609   echo \n
611 document xchartable
612 Print the address of the char-table $, and its purpose.
613 This command assumes that $ is an Emacs Lisp char-table value.
616 define xboolvector
617   xgetptr $
618   print (struct Lisp_Bool_Vector *) $ptr
619   output ($->size > 256) ? 0 : ($->data[0])@((($->size & ~gdb_array_mark_flag) + 7)/ 8)
620   echo \n
622 document xboolvector
623 Print the contents and address of the bool-vector $.
624 This command assumes that $ is an Emacs Lisp bool-vector value.
627 define xbuffer
628   xgetptr $
629   print (struct buffer *) $ptr
630   xgetptr $->name
631   output ((struct Lisp_String *) $ptr)->data
632   echo \n
634 document xbuffer
635 Set $ as a buffer pointer, assuming it is an Emacs Lisp buffer value.
636 Print the name of the buffer.
639 define xhashtable
640   xgetptr $
641   print (struct Lisp_Hash_Table *) $ptr
643 document xhashtable
644 Set $ as a hash table pointer, assuming it is an Emacs Lisp hash table value.
647 define xcons
648   xgetptr $
649   print (struct Lisp_Cons *) $ptr
650   output/x *$
651   echo \n
653 document xcons
654 Print the contents of $, assuming it is an Emacs Lisp cons.
657 define nextcons
658   p $.u.cdr
659   xcons
661 document nextcons
662 Print the contents of the next cell in a list.
663 This assumes that the last thing you printed was a cons cell contents
664 (type struct Lisp_Cons) or a pointer to one.
666 define xcar
667   xgetptr $
668   xgettype $
669   print/x ($type == Lisp_Cons ? ((struct Lisp_Cons *) $ptr)->car : 0)
671 document xcar
672 Print the car of $, assuming it is an Emacs Lisp pair.
675 define xcdr
676   xgetptr $
677   xgettype $
678   print/x ($type == Lisp_Cons ? ((struct Lisp_Cons *) $ptr)->u.cdr : 0)
680 document xcdr
681 Print the cdr of $, assuming it is an Emacs Lisp pair.
684 define xfloat
685   xgetptr $
686   print ((struct Lisp_Float *) $ptr)->u.data
688 document xfloat
689 Print $ assuming it is a lisp floating-point number.
692 define xscrollbar
693   xgetptr $
694   print (struct scrollbar *) $ptr
695 output *$
696 echo \n
698 document xscrollbar
699 Print $ as a scrollbar pointer.
702 define xprintstr
703   set $data = $arg0->data
704   output ($arg0->size > 1000) ? 0 : ($data[0])@($arg0->size_byte < 0 ? $arg0->size & ~gdb_array_mark_flag : $arg0->size_byte)
707 define xprintsym
708   xgetptr $arg0
709   set $sym = (struct Lisp_Symbol *) $ptr
710   xgetptr $sym->xname
711   set $sym_name = (struct Lisp_String *) $ptr
712   xprintstr $sym_name
714 document xprintsym
715   Print argument as a symbol.
718 define xbacktrace
719   set $bt = backtrace_list
720   while $bt
721     xgettype (*$bt->function)
722     if $type == Lisp_Symbol
723       xprintsym (*$bt->function)
724       echo \n
725     else
726       printf "0x%x ", *$bt->function
727       if $type == Lisp_Vectorlike
728         xgetptr (*$bt->function)
729         set $size = ((struct Lisp_Vector *) $ptr)->size
730         output ($size & PVEC_FLAG) ? (enum pvec_type) ($size & PVEC_TYPE_MASK) : $size & ~gdb_array_mark_flag
731       else
732         printf "Lisp type %d", $type
733       end
734       echo \n
735     end
736     set $bt = $bt->next
737   end
739 document xbacktrace
740   Print a backtrace of Lisp function calls from backtrace_list.
741   Set a breakpoint at Fsignal and call this to see from where
742   an error was signaled.
745 # Show Lisp backtrace after normal backtrace.
746 define hookpost-backtrace
747   set $bt = backtrace_list
748   if $bt
749     echo \n
750     echo Lisp Backtrace:\n
751     xbacktrace
752   end
755 define xreload
756   set $tagmask = (((long)1 << gdb_gctypebits) - 1)
757   set $valmask = gdb_use_lsb ? ~($tagmask) : ((long)1 << gdb_valbits) - 1
759 document xreload
760   When starting Emacs a second time in the same gdb session under
761   FreeBSD 2.2.5, gdb 4.13, $valmask have lost
762   their values.  (The same happens on current (2000) versions of GNU/Linux
763   with gdb 5.0.)
764   This function reloads them.
766 xreload
768 # Flush display (X only)
769 define ff
770   set x_flush (0)
772 document ff
773 Flush pending X window display updates to screen.
774 Works only when an inferior emacs is executing.
778 define hook-run
779   xreload
782 # Call xreload if a new Emacs executable is loaded.
783 define hookpost-run
784   xreload
787 set print pretty on
788 set print sevenbit-strings
790 show environment DISPLAY
791 show environment TERM
792 set args -geometry 80x40+0+0
794 # People get bothered when they see messages about non-existent functions...
795 xgetptr Vsystem_type
796 # $ptr is NULL in temacs
797 if ($ptr != 0)
798   set $tem = (struct Lisp_Symbol *) $ptr
799   xgetptr $tem->xname
800   set $tem = (struct Lisp_String *) $ptr
801   set $tem = (char *) $tem->data
803   # Don't let abort actually run, as it will make stdio stop working and
804   # therefore the `pr' command above as well.
805   if $tem[0] == 'w' && $tem[1] == 'i' && $tem[2] == 'n' && $tem[3] == 'd'
806     # The windows-nt build replaces abort with its own function.
807     break w32_abort
808   else
809     break abort
810   end
813 # x_error_quitter is defined only on X.  But window-system is set up
814 # only at run time, during Emacs startup, so we need to defer setting
815 # the breakpoint.  init_sys_modes is the first function called on
816 # every platform after init_display, where window-system is set.
817 tbreak init_sys_modes
818 commands
819   silent
820   xgetptr Vwindow_system
821   set $tem = (struct Lisp_Symbol *) $ptr
822   xgetptr $tem->xname
823   set $tem = (struct Lisp_String *) $ptr
824   set $tem = (char *) $tem->data
825   # If we are running in synchronous mode, we want a chance to look
826   # around before Emacs exits.  Perhaps we should put the break
827   # somewhere else instead...
828   if $tem[0] == 'x' && $tem[1] == '\0'
829     break x_error_quitter
830   end
831   continue
833 # arch-tag: 12f34321-7bfa-4240-b77a-3cd3a1696dfe